SaltStack技術入門與實踐


第1章 SaltStack入門

1.2.1 SaltStack軟件依賴
SaltStack有兩種消息系統,一種是REAT,一種是ZeroMQ,默認使用ZeroMQ.
軟件依賴列表如下:
●Python版本大於2.6或版本小於3.0:對Python版本要求
●msgpack-python:SaltStack消息交換庫
●YAML:SaltStack配置解析定義語法
●Jinja2: SaltStack states配置模板
●MarkupSafe: Python unicode轉換庫
●apache-libcloud: SaltStack對雲架構編排庫
●Requests: HTTP Python庫
●ZeroMQ: SaltStack消息系統
●pyzmq: ZeroMQ Python庫
●PyCrypto: Python密碼庫
●M2Crypto: Openssl Python包裝庫

1.2.2 yum方式安裝(采用EPEL源)
Master端安裝:
SaltStack@Master: rpm -vih rpm -vih http://mirrors.zju.edu.cn/epel/6/i386/epel-release-6-8.noarch.rpm
SaltStack@Master: yum install salt-master -y
SaltStack@Master: service salt-master start

Minion端安裝:
SaltStack@Minion: rpm -ivh rpm -vih http://mirrors.zju.edu.cn/epel/6/i386/epel-release-6-8.noarch.rpm
SaltStack@Minion: yum install salt-minion -y
SaltStack@Minion: sed -i 's/#master: salt/master: IPADDRESS/g' /etc/salt/minion
#IPADDRESS 為Master服務器地址
SaltStack@Minion: service salt-minion start

1.2.5 salt-bootstrap安裝
salt-bootstrap主要用於解決多平台一鍵部署SaltStack環境。核心工程機就是維護一個龐大的bash腳本。

Master端安裝:
SaltStack@Master: curl -L https://bootstrap.saltstack.com -o install_salt.sh
SaltStack@Master: sh install_salt.sh -M -N #只安裝最新版的Master

Minion端安裝:
SaltStack@Minion: echo "IPADDRESS salt" >> /etc/hosts #IPADDRESS為Master服務器地址
SaltStack@Minion: curl -L https://bootstrap.saltstack.com -o install_salt.sh
SaltStack@Minion: sh install_salt.sh -i Minion #只安裝最新版Minion並且指定Minion id

1.3 開始SaltStack之旅

1.3.1 證書管理
對Minion進行簽售證書:
SaltStack@Master: salt-key -L #查看當前證書簽售情況
SaltStack@Master: salt-key -A -y #同意簽證有沒有接受的簽證請求


#查看更多證書管理命令
SaltStack@Master: salt-key -h


SaltStack@Master: salt 'Minion' test.ping

1.3.2 日常命令參數

1.Master端
SaltStack@Master: rpm -ql salt-master
/etc/rc.d/init.d/salt-master #salt-master服務啟動腳本
/etc/salt/master #salt master配置文件
/usr/bin/salt #salt-master 核心操作命令
/usr/bin/salt-cp #salt文件傳輸命令
/usr/bin/salt-key #salt 證書管理命令
/usr/bin/salt-master #salt master服務命令
/usr/bin/salt-run #salt master runner命令
/usr/bin/salt-unity

2.Minion端
SaltStack@Minion: rpm -ql salt-minion
/etc/rc.d/init.d/salt-minion #salt minion服務啟動腳本
/etc/salt/minion #salt minion配置文件
/usr/bin/salt-call #salt call拉取命令
/usr/bin/salt-minion #salt minion服務命令

SaltStack@Minion: salt-call -h


1.4 熟悉SaltStack配置文件
SaltStack的配置文件分為Master(/etc/salt/master)和Minion(/etc/salt/minion)

1.4.1 Master配置文件
●max_open_files: 可以根據Master將Minion數量進行適當的調整
●timeout: 可以根據Master和Minion的網絡狀況適當調整
●auto_accept和autosign_file: 在大規模部署Minion的時候可以設置自動簽證
●master_tops和所有以external開頭的參數:這些參數是SaltStack與外部系統進行整合的相關配置參數

-----------------------------------------------------------------------------------------------------------
第2章 SaltStack組件

2.1 從管理對象說起

SaltStack系統中的管理對象叫做Target, 在Master上我們可以采用不同的Target去管理不同的Minion,這些Target都是通過去管理和匹配Minion的ID來做一些集合!

1.正則匹配

#想要匹配到'Min*'字符串的Minion進行操作
SaltStack@Master: salt -E 'Min*' test.ping

2.列表匹配
SaltStack@Master: salt -L Minion,Minion1 test.ping

Minion和Minion1通過列表的方式去指定Minion ID,可直接使用。

3.Grians匹配
SaltStack@Master: salt -G 'os:MacOS' test.ping

其中os:MacOS,這里的對象是一組鍵值對。

4.組匹配
SaltStack@Master: salt -N groups test.ping
groups是我們在master配置文件中定義的組名稱

5.復合匹配
SaltStack@Master: salt -C 'G@os:MacOS or L@Minion1' test.ping

os:MacOs or L@Minion1是一個復合組合,支持使用and和or關聯多個條件

6.Pillar值匹配
SaltStack@Master: salt -I 'key:value' test.ping

key:value是Pillar系統中定義的一組鍵值對,跟Grains的鍵值對類似。

7.CIDR匹配
SaltStack@Master: salt -S '192.168.1.0/24' test.ping

192.168.1.0/24是一個指定的CIDR網段,這里匹配的IP地址是Minion連接Master 4505端口的來源地址。

2.2 管理對象屬性
Grains是SaltStack記錄Minion的一些靜態信息的組件,簡單理解為Grains里面記錄着每台Minion的一些常用屬性,例如CPU、內存、磁盤、網絡信息等。
可以通過grains.items查看某台Minion的所有Grains信息。Minion的Grains信息是Minions啟動時采集匯報給Master的。

關於自定義Grains的常用方法有以下幾種:
●通過Minion配置文件定義
●通過Grains相關模塊定義
●通過Python腳本定義

Grains相關命令用法:
SaltStack@Master: salt 'Minion' sys.list_functions grains
Minion:
- grains.append
- grains.delval
- grains.filter_by
- grains.get
- grains.get_or_set_hash
- grains.has_value
- grains.items
- grains.ls
- grains.remove
- grains.setval
- grains.setvals


#查看詳細用法
salt 'Minion' sys.doc grains

2.2.1 通過Minion配置文件定義Grains
SaltStack的配置文件的默認格式都是YAML格式
為了統一管理Minion的Grains信息,需要把SaltStack的配置文件中定義grains的部分復制到minion.d/grains文件中:
SaltStack@Minion: cat /etc/minion.d/grains
grains:
roles:
- webserver
- memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15

然后/etc/init.d/salt-minion restart命令重啟Minion服務,之后可以去Master上查看定義的Grains信息是否生效:
SaltStack@Master: salt 'Minion' grains.item roles
SaltStack@Master: salt 'Minion' grains.item deployment

2.2.2 通過Grains模塊定義Grains
SaltStack@Master: salt 'Minion' grains.append saltbook 'verycool'
#設置grains信息
Minion:
---------------
saltbook:
- verycool
SaltStack@Master: salt 'Minion' grains.item saltbook #查看grains信息
Minion:
---------------
saltbook:
- verycool

可以使用grains.setvals同時設置多個Grains信息:
SaltStack@Master: salt 'Minion' grains.setvals "{'salt': 'good','book': 'cool'}"
Minion:
---------------
book:
cool
salt:
good
SaltStack@Master: salt 'Minion' grains.item salt
Minion:
---------------
salt:
good

 

上面設置的內容會被寫入到Minion端的/etc/salt/grains文件中
更多用法可通過sys.doc grains命令查詢(salt 'Minion' sys.doc grains)

2.3 數據管理中心
Pillar是數據管理中心。Pillar在SaltStack中主要的作用是存儲和定義配置管理中需要的一些數據,比如軟件版本號,用戶名密碼等信息
它的存儲定義格式也是YAML格式。
在Master配置文件中有一段Pillar settings選項專門定義Pillar相關的一些參數:
#pillar_roots:
# base:
# - /srv/pillar

默認Base環境下Pillar工作目錄在/srv/pillar目錄下。
【使用默認的配置】
首先去pillar工作目錄新建top.sls文件然后引用兩個sls文件:
SaltStack@Master: cat /srv/pillar/top.sls
base: #指定環境
'*': #Target
- packages #引用package.sls或者packages/init.sls
- services #引用services.sls或者services/init.sls
SaltStack@Master: cat /srv/pillar/packages.sls
zabbix:
package-name: zabbix
version: 2.2.4
SaltStack@Master: cat /srv/pillar/services.sls
zabbix:
port: 10050
user: admin

#查看關於pillar相關的一些模塊用法
SaltStack@Master: salt 'Minion' sys.list_functions pillar
Minion:
- pillar.data
- pillar.ext
- pillar.get
- pillar.item
- pillar.items
- pillar.raw

詳細用法和例子可通過命令salt 'Minion' sys.doc pillar查看。

#查看剛剛定義的pillar:
SaltStack@Master: salt 'Minion' pillar.item zabbix

2.4 針對管理對象操作
Module用於管理對象操作,也是SaltStack通過Push方式進行管理的入口:例如執行命令、查看安裝包情況、查看服務運行情況。

1.查看所有module列表
查看Minion支持的所有module列表的命令如下:
SaltStack@Master: salt 'Minion' sys.list_modules

2.查看指定module的所有function
查看cmd module的所有function的命令如下:
SaltStack@Master: salt 'Minion' sys.list_functions cmd

3.查看指定module用法
查看cmd module的詳細用法與例子的命令:
SaltStack@Master: salt 'Minion' sys.doc cmd

SaltStack默認也支持一次執行多個Module,Module之間通過逗號隔開,默認傳參之間也用逗號隔開,也支持指定傳參分隔符號--args-separator=@即可
SaltStacke@Master: salt 'Minion' test.echo,cmd.run,service.status,saltbook,hostname,salt-master

2.5配置管理從這里開始
States是SaltStack中的配置語言,在日常進行配置管理時需要編寫大量的States文件!

1.查看所有states列表
要查看Minion支持的所有states列表,命令如下:
SaltStack@Master: salt 'Minion' sys.list_state_modules

2.查看指定states的所有function
查看file.states的所有function,命令如下:
SaltStack@Master: salt 'Minion' sys.list_state_functions file

3.查看指定states用法
查看file.states的詳細用法:
SaltStack@Master: salt 'Minion' sys.state_doc file

4.查看指定states指定function用法
查看file.managed states的詳細用法和例子:
SaltStack@Master: salt 'Minion' sys.state_doc file.managed

5.從一個簡單的例子去了解states
使用states的流程:
●編寫top.sls文件(非必須)
●編寫states.sls文件

top.sls是states系統的入口文件,它在大規模配置管理工作中負責指定哪些設備調用哪些states.sls文件。

例如:要簡單的對某台機器進行配置管理,可直接使用state.sls命令指定states.sls文件即可,具體操作如下:
先在states的工作目錄(base環境默認在/srv/salt)下新建一個one.sls states文件:
SaltStack@Master: cat /srv/salt/one.sls
/tmp/foo.conf: #id
file.mangled: #file states的mangled functions
- source: salt://foo.conf #文件來源(salt://代表states的工作目錄)
- user: root #文件屬主
- group: root #文件屬組
- mode: 644 #文件權限
- backup:minion #備份原文件

這個states.sls文件的功能就是實現對Minion的/tmp/foo.conf文件進行統一管理。
【部署】
可以在states的工作目錄下新建一個foo.conf文件,然后對Minion進行配置部署:
SaltStack@Master: echo "SaltStack Books" > /src/salt/foo.conf
SaltStack@Master: salt 'Minion' state.sls one


使用top.sls入口文件同時對多台機器進行一個簡單的配置管理,操作如下:
首先在states的工作目錄下新建top.sls文件:
SaltStack@Master: cat /src/salt/top.sls
base: #base環境
'*': #Target(代表所有Target)
- one #引用one.sls或者one/init.sls states文件
'Minion': #Target(代表匹配Minion)
- tow #引用tow.sls或者tow/init.sls states文件
'Minion1': #Target(代表匹配Minion1)
- three #引用three.sls或者three/init.sls states文件

然后我們新建三個states文件:one.sls、tow.sls、three.sls,並使用state.highstate命令同時對Minion和Minion1兩台機器進行配置管理。

2.6執行結果處理
Return組件是SaltStack系統對執行Minion返回后的數據進行存儲或者返回給其他程序。它支持多種存儲方式,比如用MySQL,MongoDB,Redis,Memcache等
通過Return可以對SaltStack的每次操作進行記錄,對以后日志審計提供了數據來源。
官方支持30多種Return數據存儲與接口!

1.查看所有Return列表
SaltStack@Master: salt 'Minion' sys.list_returners

2.Return流程
Return是在Master端觸發任務,然后Minion接受處理任務后直接與Return存儲服務器建立連接,然后把數據Return存到存儲服務器。

3.使用Redis作為Return存儲方式
需要修改的配置信息:
●Minion配置文件
●在Minion上安裝Redis Python Client

(1)在Minion配置文件中定義Redis存儲服務器信息
redis.db: '0' #redis數據庫
redis.host: 'vps.shencan.net' #redis主機(ip地址和域名都行)
redis.port: 6379 #redis端口

(2)安裝依賴包
SaltStack@Minion: python -c 'import redis; print redis.VERSION'
如果能顯示出版本號,說明當前Python版本下的Redis Client已經安裝好!


2.7 Job管理
在SaltStack里面執行任何一個操作都會在Master上產生一個jid號。Minion端會在cache目錄下的proc目錄創建一個以jid為名稱的文件,這個文件里面的內容就是
此次操作的記錄,當操作處理完成后該文件會自動刪除。而Master端會記錄每次操作的詳細信息,這個記錄都是存到在Master端cache目錄下的jobs下。

1.通過salt-run來管理job
查看salt-run對job管理的一些用法:
SaltStack@Master: salt-run -d |grep jobs

[root@SaltStack-Master salt]# salt-run -d|grep jobs
/usr/lib64/python2.6/site-packages/Crypto/Util/randpool.py:40: RandomPool_DeprecationWarning: This application uses RandomPool, which is BROKEN in older releases. See http://www.pycrypto.org/randpool-broken
RandomPool_DeprecationWarning)
'jobs.active:'
Return a report on all actively running jobs from a job id centric
salt-run jobs.active
'jobs.last_run:'
List all detectable jobs and associated functions
salt-run jobs.last_run
salt-run jobs.last_run target=nodename
salt-run jobs.last_run function='cmd.run'
salt-run jobs.last_run metadata="{'foo': 'bar'}"
'jobs.list_job:'
salt-run jobs.list_job 20130916125524463507
'jobs.list_jobs:'
List all detectable jobs and associated functions
Search for jobs where the start time of the job is greater than
Search for jobs where the start time of the job is less than
salt-run jobs.list_jobs
salt-run jobs.list_jobs search_function='test.*' search_target='localhost' search_metadata='{"bar": "foo"}'
salt-run jobs.list_jobs start_time='2015, Mar 16 19:00' end_time='2015, Mar 18 22:00'
'jobs.list_jobs_filter:'
List all detectable jobs and associated functions
salt-run jobs.list_jobs_filter 50
salt-run jobs.list_jobs_filter 100 filter_find_job=False
'jobs.lookup_jid:'
salt-run jobs.lookup_jid 20130916125524463507
salt-run jobs.lookup_jid 20130916125524463507 outputter=highstate
'jobs.print_job:'
salt-run jobs.print_job 20130916125524463507

關於每個參數的解釋可以通過命令來查看:
salt-run -d jobs

可以通過salt-run job管理來查看job的信息。
查看某個job的運行結果:
SaltStack@Master: salt-run jobs.lookup_jid 20150503205732787057

查看這個job的詳細記錄:
SaltStack@Master: salt-run jobs.list_job 20150503205732787057


2.通過SaltStack Module來管理job
salt-run對job管理功能比較局限,目前salt-run不支持kill某個job.

#查看相關Module的用法
SaltStack@Master: salt \* sys.doc saltutil | grep job

[root@SaltStack-Master salt]# salt \* sys.doc saltutil | grep job
saltutil.find_cached_job: #查詢job cache信息
Return the data for a specific cached job id
salt '*' saltutil.find_cached_job <job id>
saltutil.find_job: #查詢job信息
Return the data for a specific job id
salt '*' saltutil.find_job <job id>
saltutil.kill_job: #殺掉job(發送SIGTERM 9信號方式)
Sends a kill signal (SIGKILL 9) to the named salt job's process
salt '*' saltutil.kill_job <job id>
salt '*' saltutil.runner jobs.list_jobs
saltutil.signal_job: #發送指定信號
Sends a signal to the named salt job's process
salt '*' saltutil.signal_job <job id> 15
saltutil.term_job: #刪掉job(發送SIGTERM 15信號方式)
Sends a termination signal (SIGTERM 15) to the named salt job's process
salt '*' saltutil.term_job <job id>

使用Module來管理job
SaltStack@Master: salt 'Minion' saltutil.find_job 20150503205732787057

直接殺掉這個job
SaltStack@Master: salt 'Minion' saltutil.kill_job 20150503205732787057

2.8 EVENT和Reactor系統
EVENT是SaltStack里面對每一個事件的一個記錄,它相對job更加底層,Event能記錄更加詳細的SaltStack事件。
例如:Minion服務啟動后請求Master簽發證書或者證書校驗的過程,都能通過Event事件來查看整個過程。
Event也為擴展SaltStack提供了更加友好的接口。

1.查看Event事件
SaltStack@Master: salt-run state.event pretty=True

2.在Master上配置Reactor
Reactor是基於Event的每個事件來做相應的操作。可以理解為Reactor系統是一直監聽着Event,然后觸發一些States操作。
當大規模新機器上線時,都希望Minion第一次起來時就能完成所有的配置,這就能通過Reactor實現。

●在Master配置文件里面添加如下內容:
reactor:
- 'salt/auth': #監聽證書認證event
- /srv/reactor/Minion.sls #執行states sls文件
- 'salt/minion/Minion/start': #監聽Minion start event
- /srv/reactor/auto.sls #執行states sls文件

●配置states文件
SaltStack@Master: cat /srv/reactor/Minion.sls
{% if 'act' in data and data['act'] == 'pend' and data['id'].startswith('Min') %}
key_accept:
wheel.key.accept:
- match: {{ data['id'] }}
{% endif %}

上述文件主要是取event里面的數據,然后根據Minion的ID進行證書簽發。

初始的auto.sls文件
SaltStack@Master: cat /srv/reactor/auto.sls
run_state:
local.state.sls
- tgt: {{ data['id'] }}
- arg:
- shencan
run_init:
local.cmd.run:
- tgt: {{ data['id'] }}
-arg:
- echo initsok >>/tmp/cpis

上述文件運行了兩個Module,一個是states.sls進行,一個是cmd.run.
run_state是針對Minion運行state.sls shencan
run_init: 是針對Minion運行cmd.run 'echo initok >> /tmp/cpis'

2.9 Renderer組件
默認SaltStack的Renderers是YAML+Jinja,可以通過查看Master配置文件得知當前的Renderer.
三種應用范圍比較廣的Renderer : YAML、Jinja、py

使用Python語言去定義state文件:
SaltStack@Master: cat /srv/salt/test.sls
#!py #指定renderer,這里為Python
def run():
example={}
example['/tmp/test'] = {
'file.managed': [
{'source': 'salt://test'},
{'mode': '644'},
{'user': 'root'},
{'template':'jinja'},
{'group':'root'},
{'context':{
'a': __grains__['os'],
'b': __pillar__['a'],
},
},
],
}
return example

state.sls文件的用途就是使用Jinja模板去同步/tmp/test文件。
通過Python定義一個run函數,函數返回一個dict。

使用Python編寫的state就是使用YAML編寫的state.
在state里面調用Pillar Grains,使用python編寫時可直接使用__grains__ __pillar__這兩個Python方法進行引用。
使用YAML編寫的state里面引入Jinja來調取grains['key'] pillar['key']

2.10 其他組件

2.10.1 Mine
Mine是SaltStack收集Minion數據存儲到Master的一個組件,功能和Grains類似!
Mine可以指定任何Minion模塊去采集數據。
Master只能存儲Minion收集上來的最近一段的數據,Mine的主要應用場景是配合前端負載均衡動態獲取Mine匯報信息,來動態生成配置文件!

Mine支持兩種配置方式:(1)通過在Minion配置文件中定義;(2)通過模塊的方式去下發Mine采集任務。

#查看Mine模塊的更多用法
sys.doc mine

2.10.2 Peer
Peer組件是SaltStack中Minion向Master發布任務的一個組件,使用Peer可以直接在Minion上向Master發布一些任務。
【配置Peer】
peer:
Minion:
- test.ping
peer_run:
Minion:
- manage.up

Peer是控制Minion執行模塊的,peer_run是控制Minion執行runner的。
下面通過在Minion上向Master發布任務:
●執行test.ping
SaltStack@Minion: salt-call publish.publish 'Minion' test.ping
●其他任務
SaltStack@Minion: salt-call publish.publish 'Minion' test.echo saltstack
●調用runner
SaltStack@Minion: salt-call publish.runner manage.up
SaltStack@Minion: salt-call publish.runner manage.down
-----------------------------------------------------------------------------------------------
第3章 SaltStack實踐案例

使用SaltStack進行生產環境配置管理,主要包括以下功能和服務:
●系統初始化
●Haproxy服務
●Keepalived服務
●Nginx服務
●PHP(FastCGI)服務
●Memcached服務

3.1環境規划

3.1.2 SaltStack環境設置
本案例使用兩個環境base和prod,base環境用來存放初始化的功能;prod環境用於放置生產的配置管理功能。
vi /etc/salt/master

#File Server Setting
file_roots:
base:
- /srv/salt/base
prod:
- /srv/salt/prod

#Pillar setting
pillar_roots:
base:
- /srv/pillar/base
prod:
- /srv/pillar/prod


創建目錄結構並重啟salt-master:
mkdir -p /srv/salt/{base,prod}
mkdir -p /srv/pillar/{base,prod}

/etc/init.d/salt-master restart

3.2 YAML編寫技巧

3.2.1 什么是YAML
YAML語法:結構使用空格來表示;項目使用"-"來表示;鍵值使用":"來分割。

3.2.2 規則一:縮進
YAML使用一個固定的縮進風格表示數據層級結構關系。
SaltStack需要每個縮進級別由兩個空格組成。

3.2.3 規則二:冒號
value可以通過縮進與key進行連接。
my_key:
my_value

對字典進行嵌套:
first_level_dict_key:
second_level_dict_key: value_in_second_level_dict

3.2.4 規則三:短橫杠
表示列表項,使用一個短橫杠加一個空格。多個項使用同樣的縮進級別作為同一列表的一部分。
- list_value_one
- list_value_two
- list_value_three

注意:每個冒號的后面都有一個空格(表示路徑的除外)!

3.3 Jinja使用技巧

3.3.1 什么是Jinja
Jinja是基於Python的模板引擎。SaltStack默認使用yaml_jinja渲染器。
yaml_jinja的流程是先用jinja2模板引擎處理SLS,然后再調用YAML解析器。

3.3.2 如何區分模板文件
在SaltStack中,files和templates都使用file這個states模塊。
通過使用template指令指定類型來區分是模板還是普通文件資源:
/etc/zabbix_agentd.conf:
file.mangled:
- name: /etc/zabbix_agentd.conf
- source: salt://zabbix/files/zabbix_agentd.conf
- templates: jinja
- defaults:
Server: {{ pillar['zabbix-agent'] ['Zabbix_Server']}}

3.3.3 Jinja基本使用
Jinja有三個步驟:
1) File狀態使用template參數 -template:jinja
2)模板文件里面變量使用{{名稱}},比如{{PORT}}
3)File狀態模塊要指定變量列表:
- defaults:
PORT:8080

Jinja變量使用Grains:
{{ grains['fqdn_ip4']}}
Jinja變量使用執行模塊:
{{ salt[network.hw_addr]('eth0') }}
Jinja變量使用Pillar:
{{ pillar['apache'] ['PORT'] }}

3.3.4 Jinja邏輯關系
Jinja用來給狀態增加邏輯關系。
例如:當你的環境同時存在CentOS和Ubuntu時,Apache軟件包的名字是不同的,通過Jinja的邏輯語法來指定:
{% if grains['os'] == 'RedHat' %}
apache: httpd
{% elif grains['os'] == 'Debian' %}
apache: apache2
{% endif %}

3.4 系統初始化
建議將所有的服務器都會涉及的基礎配置或者軟件部署歸類放在base環境下。

3.4.1 DNS配置
只需要使用SaltStack的File狀態模塊中的Mangled方法管理resolv.conf文件即可:
vi /srv/salt/base/init/dns.sls
/etc/resolv.conf
file.mangled:
- source: salt://init/files/resolv.conf
- user: root
- group: root
- mode: 644

編寫完畢后,需要將resolv.conf放置在/srv/salt/base/init/files/目錄下!

3.4.2 history記錄時間
使用SaltStack的File狀態模塊的Append方法,在/etc/profile里面追加設置:
vi /srv/salt/base/init/history.sls
/etc/profile
file.append:
- text:
- export HISTTIMEFORMAT="%F %T `whomi` "

3.4.3 命令操作審計
使用logger將輸入的命令寫入到messages,也是使用SaltStack的File模塊的Append方法。
vi /srv/salt/base/init/audit.sls
/etc/bashrc:
file.append:
- text:
- export PROMPT_COMMAND='{ msg=$(history 1 | read x y; echo $y;}); logger "[euid=$(whomi)]":$(who am i):['pwd']"$msg"; }'

3.4.4 內核參數優化
SaltStack提供了Sysctl狀態模塊用來進行內核參數的設置。

vi /srv/salt/base/init/sysctl.sls

#設置本地TCP可以使用的端口范圍
net.ipv4.ip_local_port_range:
sysctl.present:
- value: 10000 65000

#設置可以打開的最大文件數
fs.file-max:
sysctl.present:
- value: 2000000

#開啟ip轉發
net.ipv4.ip_forward:
sysctl.present:
- value: 1

#盡量不使用交換分區
vm.swappiness:
sysctl.present:
- value: 0

3.4.5 epel倉庫
下面安裝Zabbix Agent就需要epel倉庫。我們需要使用到SaltStack的pkg狀態模塊,同時還使用了unless做狀態執行的判斷。
vi /srv/salt/base/init/epel.sls
yum_repo_release:
pkg.installed:
- sources:
- epel-release: http://mirrors.aliyun.com/epel/6/x86_64/epel-release-6-8.noarch.rpm
- unless: rpm -qa| grep epel-release-6-8

3.4.6 Zabbix Agent安裝
在所有Minion都應該安裝上Zabbix Agent,主要涉及SaltStack的pkg,file,service狀態模塊以及pillar的使用。

通過使用Pillar來設置Zabbix Server的IP地址:
vi /srv/pillar/base/top.sls
base:
'*':
- zabbix

vi /srv/pillar/base/zabbix.sls
zabbix-agent:
Zabbix_Server: 192.168.1.100

安裝並啟動Zabbix Agent:
cat /srv/salt/base/init/zabbix_agent.sls
zabbix-agent:
pkg.installed:
- name: zabbix22-agent
file.mangled:
- name: /etc/zabbix_agent.conf
- source: salt://zabbix/files/zabbix_agentd.conf
- template:jinja
- defaults:
Server: {{ pillar['zabbix-agent'] ['Zabbix_Server'] }}
- require:
- pkg: zabbix-agent
service.running:
- enable: True
- watch:
- pkg: zabbix-agent
- file: zabbix-agent

Zabbix配置文件目錄用來存放用戶自定義的配置:
zabbix_agentd.conf.d:
file.directory:
- name: /etc/zabbix_agentd.conf.d
- watch_in:
- service: zabbix-agent
- require:
- pkg: zabbix-agent
- file: zabbix-agent

編寫完畢后,將zabbix_agentd.conf文件放置/srv/salt/base/init/files/目錄下,同時修改如下:
Include=/etc/zabbix_agentd.conf.d #修改或增加
Server={{Server}} #修改此行

3.4.7 初始化環境引用
再編寫一個sls將初始化的功能都包括進來:
vi /srv/salt/base/init/env_init.sls
include:
- init.dns
- init.history
- init.audit
- init.sysctl
- init.epel
- zabbix_agent


在top.sls里面給Minion指定狀態並執行:
vi /srv/salt/base/top.sls
base:
'*':
- init.env_init


#對執行狀態進行測試
salt '*' state.highstate test=true

#在所有Minion上執行狀態
salt '*' state.highstate


3.5 Haproxy配置管理
Haproxy支持四層和七層的負載均衡,多種負載均衡算法和健康檢查。

創建目錄結構:
mkdir -p /srv/salt/prod/pkg
mkdir -p /srv/salt/prod/haproxy/files
mkdir -p /srv/salt/prod/keepalived/files

3.5.1 pkg配置
使用pkg模塊將源碼編譯依賴的各種包都安裝上,使用pkg狀態模塊的installed方法,同時使用了names列表。

vi /srv/salt/prod/pkg/pkg-init.sls
pkg-init:
pkg.installed:
- names:
- gcc
- gcc-c++
- glibc
- make
- autoconf
- openssl
- openssl-devel

3.5.2 Haproxy服務管理
首先將haproxy源碼包和管理腳本放置在/srv/salt/prod/haproxy/files目錄下。

●將軟件包復制到haproxy的files目錄下
cd /usr/local/src/
cp haproxy-1.5.3.tar.gz /srv/salt/test/haproxy/files/
tar zxf haproxy-1.5.3.tar.gz
cd /usr/local/src/haproxy-1.5.3/examples/

該目錄下存放了haproxy啟動腳本,修改下路徑:
sed -i 's/\/usr\/sbin\/'\$BASENAME'/\/usr\/local\/haproxy\/sbin\/'\$BASENAME/g' haproxy.init
●復制到haproxy的files目錄下
cp haproxy.init /srv/salt/test/haproxy/files/

3.5.3 編寫haproxy安裝SLS
安裝腳本:
vi /srv/salt/prod/haproxy/install.sls
include:
- pkg.pkg-init
haproxy-install:
file.managed:
- name: /usr/local/src/haproxy-1.5.3.tar.gz
- source: salt://haproxy/files/haproxy-1.5.3.tar.gz
- mode: 755
- user: root
- group: root
cmd.run:
- name: cd /usr/local/src && tar zxf haproxy-1.5.3.tar.gz && cd haproxy-1.5.3 && TARGET=linux26 PREFIX=/usr/local/haproxy && make install PREFIX=/usr/local/haproxy
- unless: test -d /usr/loca/haproxy
- require:
- pkg: pkg-init
- file: haproxy-install


Haproxy的服務管理腳本:
/etc/init.d/haproxy:
file.managed:
- source: salt://haproxy/files/haproxy.init
- mode: 755
- user: root
- group: root
- require:
- cmd: haproxy-install

設置可以監聽非本地IP:
net.ipv4.ip_nonlocal_bind:
sysctl.present:
- value: 1

Haproxy的配置文件存放目錄:
haproxy-config-dir:
file.directory:
- name: /etc/haproxy
- mode: 755
- user: root

將Haproxy加入到系統服務中:
haproxy-init:
cmd.run:
- name:chkconfig --add haproxy
- unless: chkconfig --list|grep haproxy
- require:
- file: /etc/init.d/haproxy

管理Haproxy的配置文件的兩種方法:
●直接在需要使用haproxy的地方引用haproxy的安裝,然后加入haproxy的配置文件管理和服務管理。
●使用Jinja模板,將haproxy的基礎配置編寫完成后,其他的配置通過Pillar來進行自動生成;

3.5.4 Haproxy業務引用
現在編寫一個業務模塊Cluster,然后調用Haproxy來完成配置管理。這樣可以很好的把基礎服務的配置管理和業務分開。
●創建cluster目錄,並且在cluster目錄創建files目錄,用來存放配置文件:
mkdir -p /srv/salt/prod/cluster/files
●將haproxy配置文件放置在/srv/salt/prod/cluster/files目錄下,以下為最小化配置:
cat /srv/salt/prod/cluster/files/haproxy-outside.cfg
global
maxconn 100000
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
log 127.0.0.1 local3 info
●默認參數配置如下:
defaults
option http-keep-alive
maxconn 100000
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
●開啟haproxy Status狀態監控,增加驗證:
listen stats
mode http
bind 0.0.0.0:8888
stats enable
stats uri /haproxy-status
stats auth haproxy:saltstack
●前端設置如下:
frontend frontend_www_example_com
bind 192.168.56.20:80
mode http
option httplog
log global
default_backend backend_www_example_com

●后端設置如下:
backend backend_www_example_com
option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0
balance source
server web-node1 192.168.56.21:8080 check inter 2000 rise 30 fall 15
server web-node2 192.168.56.22:8080 check inter 2000 rise 30 fall 15

編寫haproxy服務管理:
vi /srv/salt/prod/cluster/haproxy-outside.sls
include:
- haproxy.install
haproxy-service:
file.managed:
- name: /etc/haproxy/haproxy.cfg
- source: salt://cluster/files/haproxy-outside.cfg
- user: root
- group: root
- mode: 644
service.running:
- name: haproxy
- enable: True
- reload: True
- require:
- cmd: haproxy-init
- watch:
- file: haproxy-service

3.5.5 執行haproxy狀態
在top file中給Minion指定狀態。
SaltStack-node1: vi /srv/salt/base/top.sls
base:
'*':
- init.env_init
prod:
'*':
- cluster.haproxy-outside

測試並執行狀態:
[root@saltstack-node1 ~]# salt '*' state.highstate test=True
[root@saltstack-node1 ~]# salt '*' state.highstate

3.5.6 查看haproxy狀態
啟動haproxy,通過瀏覽器http://IP地址:8888/haproxy-status查看haproxy狀態。


3.6 Keepalived配置管理
首先放置源碼包、keepalived的啟動腳本、sysconfig配置文件在/srv/salt/prod/keepalived/files/目錄下。

3.6.1 軟件包准備
cd /usr/local/src/
wget http://www.keepalived.org/software/keeaplived-1.2.17.tar.gz

復制到Keepalived的files目錄下,並解壓:
cp keepalived-1.2.17.tar.gz /srv/salt/prod/keepalived/files
tar xvf keepalived-1.2.17.tar.gz
cd keepalived-1.2.17

將keepalived需要的init腳本的sysconfig復制到files目錄下:
cp keepalived/etc/init.d/keepalived.init /srv/salt/prod/keepalived/files/
cp keepalived/etc/init.d/keeaplived.sysconfig /srv/salt/prod/keepalived/files/

手動修改源碼包里面的init腳本:
vi /srv/salt/prod/keepalived/files/keepalived.init
將daemon keepalived ${KEEPALIVED_OPTIONS}
修改為: daemon /usr/local/keepalived/sbin/keeaplived ${KEEPALIVED_OPTIONS}

3.6.2 編寫keepalived安裝SLS
編寫keepalived安裝配置:
vi install.sls
keepalived-install:
file.managed:
- name: /usr/local/src/keepalived-1.2.17.tar.gz
- source: salt://keepalived/files/keepalived-1.2.17.tar.gz
- mode: 755
- user: root
- group: root
cmd.run:
- name: cd /usr/local/src && tar zxf keepalived-1.2.17.tar.gz && cd keepalived-1.2.17 && ./configure --prefix=/usr/local/keepalived --disable-fwmark && make && make install
- unless: test -d /usr/local/keepalived
- require:
- file: keepalived-install

Keepalived的sysconfig配置文件:
/etc/sysconfig/keepalived:
file.managed:
- source: salt://keepalived/files/keepalived.sysconfig
- mode: 644
- user: root
- group: root

Keepalived的服務管理腳本:
/etc/init.d/keepalived:
file.managed:
- source: salt://keepalived/files/keepalived.init
- mode: 755
- user: root
- group: root

將Keepalived加入系統服務管理:
keepalived-init:
cmd.run:
- name: chkconfig --add keepalived
- unless: chkconfig --list|grep keepalived
- require:
- file: /etc/init.d/keepalived

Keepalived的配置文件目錄:
/etc/keepalived:
file.directory:
- user: root
- group: root

3.6.3 Keepalived業務引用
下面列出Keepalived做haproxy高可用的一個最小化的配置模板,該模板文件放置在/srv/salt/prod/cluster/files/目錄下。
vi /srv/salt/prod/cluster/files/haproxy-outside-keepalived.conf
! Configuration File For keepalived
global_defs {
notification_email {
saltstack@example.com
}
notification_email_from keepalived@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id {{ ROUTEID}}
}

vrrp_instance haproxy_ha {
state {{STATEID}}
interface eth0
virtual_router_id 36
priority {{PRIORITYID}}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.56.20
}
}

在Cluster業務目錄下編寫Haproxy使用Keepalived做高可用的sls:
cat /srv/salt/prod/cluster/haproxy-outside-keepalived.sls
include:
- keepalived.install
keepalived-server:
file.managed:
- name: /etc/keepalived/keepalived.conf
- source: salt://cluster/files/haproxy-outside-keepalived.conf
- mode: 644
- user: root
- group: root
- template: jinja

{% if grains['fqdn'] == 'saltstack-node1.example.com' %}
- ROUTEID: haproxy_ha
- STATEID: MASTER
- PRIORITYID: 150

{% elif grains['fqdn'] == 'saltstack-node2.example.com' %}
- ROUTEID: haproxy_ha
- STATEID: BACKUP
- PRIORITYID: 100
{% endif %}
service.running:
- name: keepalived
- enable: True
- watch:
- file: keepalived-server

在這個描述文件中,使用了Jinja模板的判斷函數,通過grains獲取服務器的FQDN名,然后根據不同的FQDN名設置不同變量的值。將saltstack-node1.example.com設置
為Keepalived的主節點,另外一台設置為Keepalived的備節點。

3.6.4 執行Keepalived狀態
編寫完畢后,在top file里面指定Minion運行該狀態:
vi /srv/salt/base/top.sls
base:
'*':
- init.env_init
prod:
'*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived

3.6.5 Haproxy+Keepalived測
可以使用ip ad li查看目前的VIP是否在該節點: ip ad li eth0


3.7 Memcached配置管理
在負載均衡環境下遇到Session問題,一般的解決方法有三種:
●Session保持
●Session復制
●Session共享

創建目錄結構:
mkdir -p /srv/salt/prod/{libevent,memcached}/files
mkdir /srv/salt/prod/user

3.7.1 www用戶配置
啟動memcached需要使用www用戶,我們將www用戶的配置單獨放置在user目錄下:
vi /srv/salt/prod/user/www.sls
www-user-group:
group.present:
- name: www
- gid: 1000
user.present:
- name: www
- fullname: www
- shell: /sbin/nologin
- uid: 1000
- gid: 1000

3.7.2 libevent配置
源碼包:
cd /srv/salt/prod/libevent/files/

編寫Libevent部署SLS:
vi /srv/salt/prod/libevent/install.sls
libevent-source-install:
file.managed:
- name: /usr/local/src/libevent-2.0.22-stable.tar.gz
- source: salt://libevent/files/libevent-2.0.22-stable.tar.gz
- user: root
- group: root
- mode: 644
cmd.run:
- name: cd /usr/local/src && tar zxf libevent-2.0.22-stable.tar.gz && cd libevent-2.0.22-stable && ./configure --prefix=/usr/local/libevent && make && make install
- unless: test -d /usr/local/libevent
- require:
- file: libevent-source-install

3.7.3 Memcached配置
編寫Memcached部署SLS如下:
vi /srv/salt/prod/memcached/install.sls
include:
- libevent.install
memcached-source-install:
file.managed:
- name: /usr/local/src/memcached-1.4.24.tar.gz
- source: salt://memcached/files/memcached-1.4.24.tar.gz
- user: root
- group: root
- mode: 644
cmd.run:
- name: cd /usr/local/src && tar zxf memcached-1.4.24.tar.gz && cd memcached-1.4.24 && ./configure --prefix=/usr/local/memcached --enable-64-bit --with-libevent=/usr/local/libevent && make && make install
- unless: test -d /usr/local/memcached
- require:
- cmd: libevent-source-install
- file: memcached-source-install

3.7.4 Memcache服務
使用cmd.run來啟動memcached進程。
vi /srv/salt/prod/memcached/service.sls
include:
- memcached.install
- user.www

memcached-service:
cmd.run:
- name: /usr/local/memcached/bin/memcached -d -m 128 -p 11211 -c 8096 -u www
- unless: netstat -ntlp|grep 11211
- require:
- cmd: memcached-source-install
- user: www-user-group

3.7.5 執行Memcached狀態
在top file里面進行定義:
vi /srv/salt/base/top.sls
base:
'*':
- init.env_init
prod:
'*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived
'saltstack-node2.example.com':
- memcached.service

先測試后執行狀態:
salt '*' state.highstate test=True
salt '*' state.highstate

3.8 Nginx配置管理
Nginx+PHP需要安裝的包首先有Nginx和PHP,需要進行編譯安裝,步驟如下:
1)所有源碼包的編譯安裝需要依賴一些基礎安裝包,像gcc,make
2)源碼編譯安裝Nginx時需要依賴PCRE,所以需要有一個PCRE模塊來安裝PCRE,然后Nginx進行include即可
3)需要編譯安裝PHP,除了PHP常用的模塊之外,還應該支持Memcached和Redis這樣的第三方模塊。

需要使用到的功能如下:
●使用狀態模塊: file,cmd,service
●使用狀態間關系: require,unless
●SLS之間的include

創建目錄結構:
mkdir -p /srv/salt/prod/{pcre,nginx,php}/files
創建完目錄結構后,需要把源碼包放置在各個服務目錄的files目錄下:
wget http://nginx.org/download/nginx-1.8.0.tar.gz
cp nginx-1.8.0.tar.gz /srv/salt/prod/nginx/files
wget http://cn2.php.net/distributions/php-5.6.9.tar.gz

3.8.1 PCRE模塊
編寫狀態文件如下:
vi /srv/salt/prod/pcre/install.sls
pcre-source-install:
file.managed:
- name: /usr/local/src/pcre-8.37.tar.gz
- source: salt://pcre/files/pcre-8.37.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf pcre-8.37.tar.gz && cd pcre-8.37 && ./configure --prefix=/usr/local/pcre && make && make install
- unless: test -d /usr/local/pcre
- require:
- file: pcre-source-install

3.8.2 Nginx模塊
編寫狀態文件:
vi /srv/salt/prod/nginx/install.sls
#將PCRE的安裝包含進來
include:
- pcre.install
- user.www
#Nginx編譯安裝
nginx-source-install:
file.managed:
- name: /usr/local/src/nginx-1.9.1.tar.gz
- source: salt://nginx/files/nginx-1.9.1.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf nginx-1.9.1.tar.gz && cd nginx-1.9.1 && ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-file-aio --with-http_dav_module --with-pcre=/usr/local/src/pcre-8.37 && make && make install && chown -R www:www /usr/local/nginx
- unless: test -d /usr/local/nginx
- require:
- user: www-user-group
- file: nginx-source-install
- pkg: pkg-init
- cmd: pcre-source-install

3.8.3 Nginx配置文件
Nginx模塊作為基礎模塊,nginx.conf里面寫的是所有業務公用的配置,然后每個業務具體的Server配置通過Nginx的include指令來實現。
vi /srv/salt/prod/nginx/files/nginx.conf
user www;
worker_processes 16;
error_log logs/error.log error;
worker_rlimit_nofile 30000;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535;
}

http {
include mime.type;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
underscores_in_headers on;
keepalive_timeout 10;
send_timeout 60;
include /usr/local/nginx/conf/vhost/*.conf;
server {
listen 8080;
server_name 127.0.0.1
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}

3.8.4 編寫Nginx服務SLS
單獨編寫Nginx的service.sls以啟動服務和增加配置文件。
vi /srv/salt/prod/nginx/service.sls
include:
- nginx.install
nginx-init:
file.managed:
- name: /etc/init.d/nginx
- source: salt://nginx/files/nginx-init
- mode: 755
- user: root
- group: root
cmd.run:
- name: chkconfig --add nginx
- unless: chkconfig --list|grep nginx
- require:
- file: nginx-init
/usr/local/nginx/conf/nginx.conf
file.managed:
- source: salt://nginx/files/nginx.conf
- user: www
- group: www
- mode: 644
nginx-service:
file.directory:
- name: /usr/local/nginx/conf/vhost
- require:
- cmd: nginx-source-install
service.running:
- name: nginx
- enable: True
- reload: True
- require:
- cmd: nginx-init
- watch:
- file: /usr/local/nginx/conf/nginx.conf

3.8.5 PHP(FastCGI)配置管理
對於PHP的源碼編譯安裝,使用FastCGI模式,FastCGI模式涉及三個文件:php.ini, php-fpm.conf和fastcgi的啟動腳本。
vi /srv/salt/prod/php/install.sls
pkg-php:
pkg.installed:
- names:
- mysql-devel
- openssl-devel
- swig
- libjpeg-turbo
- libjpeg-turbo-devel
- libpng
- libpng-devel
- freetype
- freetype-devel
- libxml2
- libxml2-devel
- zlib
- zlib-devel
- libcurl
- libcurl-devel
php-source-install:
file.managed:
- name: /usr/local/src/php-5.6.9.tar.gz
- source: salt://php/files/php-5.6.9.tar.gz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf php-5.6.9.tar.gz && cd php-5.6.9 && ./configure --prefix=/usr/local/php-fastcgi --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-mysql=mysqlnd
--with-jpeg-dir --with-png-dir --with-zlib --enable-xml --with-libxml-dir --with-curl --enable-bcmatch --enable-shmop
--enable-sysvsem --enable-inline-optimization --enable-mbregex --with-openssl --enable-mbstring --with-gd --enable-gd-native-ttf
--with-freetype-dir=/usr/lib64 --with-gettext=/usr/lib64 --enable-sockets --with-xmlrpc --enable-zip --enable-soap
--disable-debug --enable-opcache --enable-zip --with-config-file-path=/usr/local/php-fastcgi/etc --enable-fpm
--with-fpm-user=www --with-fpm-group=www && make && make install
- require:
- file: php-source-install
- user: www-user-group
- unless: test -d /usr/local/php-fastcgi

pdo-plugin:
cmd.run:
- name: cd /usr/local/src/php-5.6.9/ext/pdo_mysql/ && /usr/local/php-fastcgi/bin/phpize && ./configure --with-php-config=/usr/local/php-fastcgi/bin/php-config && make && make install
- unless: test -f /usr/loca/php-fastcgi/lib/php/extensions/*/pdo_mysql.so
- require:
- cmd: php-source-install

php-ini:
file.managed:
- name: /usr/local/php-fastcgi/etc/php.ini
- source: salt://php/files/php.ini-production
- user: root
- group: root
- mode: 644

php-fpm:
file.managed:
- name: /usr/local/php-fastcgi/etc/php-fpm.conf
- source: salt://php/files/php-fpm.conf.default
- user: root
- group: root
- mode: 644

php-fastcgi-service:
file.managed:
- name: /etc/init.d/php-fpm
- source: salt://php/files/init.d.php-fpm
- user: root
- group: root
- mode: 755
cmd.run:
- name: chkconfig --add php-fpm
- unless: chkconfig --list | grep php-fpm
- require:
- file: php-fastcgi-service
service.running:
- name: php-fpm
- enable: True
- require:
- cmd: php-fastcgi-service
- watch:
- file: php-ini
- file: php-fpm

3.8.6 PHP Redis模塊
vi /srv/salt/prod/php/php-redis.sls
redis-plugin:
file.managed:
- name: /usr/local/src/phpredis-2.2.7.tgz
- source: salt://php/files/phpredis-2.2.7.tgz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf phpredis-2.2.7.tgz && cd phpredis-2.2.7 && /usr/local/php-fastcgi/bin/phpize && ./configure --with-php-config=/usr/local/php-fastcgi/bin/php-config && make && make install
- unless: test -f /usr/local/php-fastcgi/lib/php/extensions/*/redis.so
- require:
- file: redis-plugin
- cmd: php-install
/usr/local/php-fastcgi/etc/php.ini:
file.append:
- text:
- extensions=redis.so

3.8.7 PHP Memcached模塊
PHP連接memcache有兩個擴展模塊:Memcache和Memcached.

PHP memcache擴展包如下:
vi /srv/salt/prod/php/php-memcache.sls
memcache-plugin:
file.managed:
- name: /usr/local/src/memcache-2.2.7.tgz
- source: salt://php/files/memcache-2.2.7.tgz
- user: root
- group: root
- mode: 755
cmd.run:
- name: cd /usr/local/src && tar zxf memcache-2.2.7.tgz && cd memcache-2.2.7 && /usr/local/php-fastcgi/bin/phpize && ./configure --enable-memcache --with-php-config=/usr/local/php-fastcgi/bin/php-config && make && make install
- unless: test -f /usr/local/php-fastcgi/lib/php/extensions/*/memcache.so
- require:
- file: memcache-plugin
- cmd: php-install
/usr/local/php-fastcgi/etc/php.ini:
file.append:
- text:
- extension=memcache.so

3.9 業務應用模塊

3.9.1 BBS論壇案例
安裝Nginx+PHP環境和PHP Memcache模塊!
(1)創建目錄結構
mkdir -p /srv/salt/prod/web/files/
(2)給一個Nginx虛擬主機配置文件的例子
vi /srv/salt/prod/web/files/bbs/conf
server {
listen 8080;
root /usr/local/nginx/html;
index index.htm index.html index.php
location ~ \.php\$
{
fastcgi_pass unix:/usr/local/php-fastcgi/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
}

編寫bbs.sls
vi /srv/salt/prod/web/bbs.sls
include:
- php.install
- nginx.service

web-bbs:
file.managed:
- name: /usr/local/nginx/conf/vhost/bbs.conf
- source: salt://web/files/bbs.conf
- user: root
- group: root
- mode: 644
- require:
- service: php-fastcgi-service
- watch:
- service: nginx-service

3.9.2 修改top.sls
vi /srv/salt/base/top.sls
base:
'*':
- init.env_init
prod:
'*':
- cluster.haproxy-outside
- cluster.haproxy-outside-keepalived
- web.bbs
'saltstack-node2.example.com':
- memcached.service


3.9.4 案例擴展的思路
●使用Grains區分不同的操作系統
●使用Pillar實現更靈活的配置文件管理
●修改案例的狀態文件,使用更好的編寫方法
●如何將現有環境中的各種服務使用SaltStack進行管理


----------------------------------------------------------------------------------------------------------------------------------------

第4章 擴展SaltStack組件

4.1 擴展Grains
Grains能收集Minion的各種靜態信息!

4.1.1 理解擴展Grains流程
擴展Grains流程:
(1)在Master上編寫一個Python腳本。這個腳本的主要內容是定義如何收集你想要的信息。在腳本的最后把采集到的各種信息返回。
(2)需要把這個腳本sync同步到所有的Minion上。

Python腳本內容如下:
cat /srv/salt/_grains/example.py
#!/bin/python
def grains():
local={}
test={'key':'value','key1':'value1','key2':'value2'}
local['list']= [1,2,3,4]
local['string'] = 'str'
local['dict'] = test
return local

將腳本同步到minion上:
SaltStack@Master: salt 'Minion' saltutil.sync_grains
文件默認被同步到Minion端的/var/cache/salt/minion/extmods/grains/目錄下!

第二種方法:
salt '*' cp.get_file salt://_grains/example.py /tmp/example.py

說明:Python腳本存放在Master端的/srv/salt/_grains目錄下,將其復制到Minion端的/tmp目錄下。其中salt://表示的就是/srv/salt,這個參數在Master配置文件/etc/salt/master中的file_roots進行定義。

#查看Python腳本是否復制到Minion端
salt '*' cmd.run 'ls /var/cache/salt/minion/extmods/grains/'

#在Master端查看使用腳本定義的Grains信息
salt '*' grains.item list string dict

4.1.2 擴展Grains案例


[root@SaltStack-Master _grains]# more info.py
#!/usr/bin/python
import commands
import simplejson
import urllib

def role():
information={}
information['disk_num'] = commands.getoutput('fdisk -l|grep Disk|wc -l')
information['disk_big'] = commands.getoutput("fdisk -l|grep Disk|grep /dev/sda1|awk '{print $3}'")
f=open('/etc/sysconfig/network')
line=f.readlines()
for i in list(line):
if i.split('=')[0] == 'HOSTNAME':
host=i.split('=')[1]
a=urllib.urlopen('http://192.168.236.101:36000/device/' + host).read()
ldev = simplejson.loads(a)
for dev in ldev:
if dev.has_key('appList'):
for app in dev['appList']:
if app.startswith('CPISF'):
information['type']= app
information['node']= '-'.join(host.split('-')[1:3])
return information

4.2 擴展Module

4.2.1 理解擴展Module原理
cat /usr/lib/python2.6/site-packages/salt/modules/dig.py

# -*- coding:utf-8 -*-
'''
compendium of generic DNS utilities
'''
from __future__ import absolute_import

#Import python libs
import logging
import re
import socket

log = logging.getLogger(__name__)

__virtualname__ = 'dig'

def __virtual__():
'''
Only load module if dig binary is present
'''
return True if salt.utils.which('dig') else False


def A(host,nameserver=None):
'''
Return the A record for ``host``.
Always returns a list.
CLI Example:
.. code-block:: bash
salt nsl dig.A.www.google.com
'''
dig = ['dig','+short',str(host),'A']
if nameserver is not None:
dig.append('@{0}'.format(nameserver))

cmd = __salt__['cmd.run_all'](dig,python_shell=False)
#In this case,0 is not the same as False
if cmd['recode'] !=0:
log.warn(
'dig returned exit code \'{ 0}\'.Returning empty list as '
'failback.'.format(
cmd['retcode']
)
)
return []
return [x for x in cmd['stdout'].split('\n') if check_ip(x) ]

4.2.2 擴展Module案例
cat /srv/salt/_modules/puppet.py
#!/usr/bin/python
# -*- coding:utf-8 -*-

from __future__ import absolute_import
from salt.ext.six.moves.urllib.request import urlopen as _urlopen
import salt.utils
import salt.utils.decorators as decorators
@decorators.memoize
def __detect_os():
return salt.utils.which('puppet')

def __virtual__():
if __detect_os():
return True
return False

def setmaster(master='www.shencan.net',config_file='/etc/puppet/puppet.conf'):
'''
salt \* puppet.setmaster www.shencan.net
:param master:
:param config_file:
:return:
'''
check = 'grep server {0}'.format(config_file)
outcheck = __salt__['cmd.run'](check)
if outcheck:
cmdline = 'sed -i "s/server = .*/server = {0}/g" {1}'.format(master,config_file)
output = __salt__['cmd.run'](cmdline)
return 'has change server to {0}'.format(master)
else:
cmdline = 'echo " server = {0}" >> {1}'.format(master,config_file)
output = __salt__['cmd.run'](cmdline)
return 'has change server to {0} need restart the service'.format(master)

def version():
'''
salt '*' puppet.version
:return:
'''
cmd = 'rpm -qf {0}'.format(__detect_os())
output = __salt__['cmd.run'](cmd).splitlines()
ret = output[0].split(':')
return ret[-1]

def service(signal=None):
'''
salt '*' puppet.service start
:param signal:
:return:
'''
status = ('start','stop','status','restart','reload','force-reload','condrestart','once','genconfig')
if signal not in status:
return 'puppet can not support this signal'
cmdline = '/etc/init.d/puppet' + '{0}'.format(signal)
output = __salt__['cmd.run'](cmdline)
return output

def master(config_file='/etc/puppet/puppet.conf'):
'''
salt \* puppet.master
:param config_file:
:return:
'''
cmdline='grep server' + '{0}'.format(config_file)
output = __salt__['cmd.run'](cmdline,python_shell=False)
if output:
return output
else:
return 'puppet server not setting'


上述腳本包含的4個主要函數,實現4個功能:
●setmaster函數主要指定puppetserver地址
●version函數是查看minion上puppet的版本
●service函數是去管理puppet的服務狀態
●master函數是查看目前puppet配置文件里面定義的server地址

4.3 擴展state

4.3.1 理解擴展state原理

4.4 ext_pillar與ext_nodes

4.4.2 理解ext_nodes流程和案例
官方關於top.sls通過動態方式的方式只有四種形式:
1)通過從MongoDB里面獲取Minion與state.sls文件的對應關系:
master_tops:
mongo:
collection:tops
id_field: _id
re_replace:""
re_pattern: \.example\.com
states_field: states
environment_field: environment
2)通過ext_nodes的形式:
master_tops:
ext_nodes: cobbler-ext-nodes
3)通過reclass_adapter的形式:
master_tops:
reclass:
storage_type:yaml_fs
inventory_base_uri: /srv/salt

4)通過cobbler直接獲取的方式:
master_tops:
cobbler: {}
cobbler.url: https://example.com/cobbler_api #defauts is http://localhost/cobbler_api
cobbler.user: username #default is no username
cobbler.password: password #default is no password

4.5 SaltStack Git 文件服務器

 

 


----------------------------------------------------------------------------------------------------------
第5章 第三方調用SaltStack

除了salt命令之外,SaltStack還提供了另外兩個與其交互的途徑:
●只有在salt Master本機才能使用Python API
●可以在遠程通過HTTP調用的API

5.1 通過Python API調用

5.1.1 Python API工作原理

1.實例以及工作流程解析
Salt本身的操作實際上在底層都是以一個消息來傳輸並解析執行的,實際上API要做的就是模擬一個消息並發送到該發送的地方;
Python API就是提供了一個程序的接口,讓大家可以很容易的通過這個接口來給SaltStack發送消息。

2.通過API獲取SaltStack配置
有些Salt的API接口需要讀取SaltStack的opts的目錄。

【獲取Master配置信息】
#導入saltstack的配置模塊
import salt.config

#讀取saltstack的配置文件(/etc/salt/master)並賦值給master_opts
master_opts=salt.config.client_config('/etc/salt/master')

#查看master_opts的屬性
dir(master_opts)

#查看master_opts類型
type(master_opts)

#以字典形式打印
print dict(master_opts)


【獲取Minion配置信息】
#導入salt客戶端
import salt.client

#獲取客戶端配置,並賦值給minion_opts
minion_opts=salt.config.minion_config('/etc/salt/minion')

#查看minion_opts屬性
dir(minion_opts)

#查看minion_opts類型
type(minion_opts)

#查看minion_opts的key
minion_opts.keys()


5.1.2 Python API介紹

1.LocalClient
SaltStack默認使用此接口。該接口默認只能在Salt Master本機調用:
>>>import salt.config
>>>local = salt.client.LocalClient()
>>>local.cmd('*','cmd.run',['whoami'])

核心方法
cmd(tgt,fun,arg=(),timeout=None,expr_form='glob',ret='',jid='',kwarg=None,**kwargs)
●tgt: 即target,執行該命令的目標機器、字符串或列表
●fun: 字符串或列表,執行的模塊

支持一次執行多個模塊命令、一次對多個模塊進行調用時,需要arg和fun都是一個列表,而且兩者的順序要一一對應。
當某個模塊沒有參數時,在arg里放一個空列表。代碼如下:
local.cmd('*',[
'grains.items',
'sys.doc',
'cmd.run',
],
[
[],
[],
['uptime'],
])

參數說明如下:
●arg: 列表或者一個由列表組成的列表,對應模塊的參數;
●timeout: Minion返回的超時時間
●expr_form: 匹配模式,可選項:glob,pcre,list,grain,grain_pcre,pillar,pillar_pcre,noegroup,range,compund
●ret: 使用的returner,一個或者多個returner(多個用逗號隔開)
●kwarg: 方法的字典形式參數
●kwargs: 可選的參數

使用external_auth時,token可以當作一個可選參數,如:
local.cmd('*','test.ping',username='saltdev',password='saltdev',eauth='pam')
local.cmd('*','test.ping',token='5871821a51754fdcea8153c1c745433')

其他方法

●異步執行
cmd_async(tgt,fun,arg=(),expr_form='glob',ret='',jid='',kwarg=None, **kwargs)
●批量執行
cmd_batch(tgt,fun,arg=().expr_form='glob',ret='',kwarg=None,batch='10%',**kwargs)
●隨機執行
cmd_subset(tgt,fun,arg=(),expr_form='glob',ret='',kwarg=None,sub=3,cli=False,progress=False,**kwargs)

 

2.Salt Caller
Salt Caller的功能是在Minion端通過API調用SaltStack,salt-call后端調用的就是這個接口。

3.RunnerClient
RunnerClient的功能是在Master端通過Python調用runner(調用此接口的系統用戶需與運行Master的用戶一致).
Salt-run后端調用的是這個接口。

4.WheelClient
為SaltStack wheel模塊提供的程序接口(調用此接口的系統用戶需與運行Master的用戶一致)
>>>opts=salt.config.master_config('/etc/salt/master')
>>>wheel=salt.wheel.Wheel(opts)
>>>wheel.call_func('key.list_all')

5.2 通過RESTful API調用
當我們在其他機器或者通過第三方調用SaltStack時,就需要這個。

5.2.1 SaltStack的API是在Master和Minion之外的一個獨立的服務,所以需要獨立部署,API服務需要部署在Master服務器上。

1.部署Salt-API服務
yum install gcc make python-devel libffi-devel
pip-python install PyOpenSSL

#生成證書
salt-call tls.create_self_signed_cert

#安裝軟件
yum install -y salt-api

2.配置用戶以及權限
cat /etc/salt/master.d/eauth.conf
external_auth:
pam: 認證模式
saltapi: #用戶名
- . #用戶權限
- '@wheel'
- '@runner'


#添加用戶
useradd -M -s /sbin/nologin saltapi
echo "spassword" |passwd saltapi --stdin

3.配置salt-api服務
cat /etc/salt/master.d/api.conf
rest_cherrypy:
port:8000
ssl_crt: /etc/pki/tls/certs/localhost.crt #使用前面生成的證書
ssl_key: /etc/pki/tls/certs/localhost.key

4.啟動服務
/etc/init.d/salt-api restart
netstat -lnp|grep 8000

5.2.2 通過Restfu API實現日常操作
1)運行遠程模塊
2)查詢指定job
3)運行runner

 

 

---------------------------------------------------------------------------------------------
第6章 SaltStack架構擴展

6.1 無Master架構

6.1.1 設置無Master運行
讓Salt Minion在無Master的架構下運行,需要修改Minion的配置文件。
將file_client修改為local,默認是remote。同時還需要和Salt Master一樣,設置file_roots和pillar_roots
vi /etc/salt/minion
file_client: local
file_roots:
base:
- /srv/salt/
pillar_roots:
base:
- /srv/pillar


6.1.2 關閉salt-minion
/etc/init.d/salt-minion stop


6.1.3 使用salt-call執行狀態
使用salt-call命令,如下所示:
salt-call --local state.highstate

--local: 告訴salt-minion在本地文件系統上尋找state tree,而不是連接Salt Master.


6.2 多Master架構

6.2.1 配置多Master
yum -y install salt-master

6.2.2 Master數據存儲
哪些master上的數據需要在所有Master之間進行數據的同步,有如下幾種:
1.Master Keys
多Master的配置中,所有的Master使用同樣的private key.這些private key是在Master第一次啟動時自動生成的,所以在多Master環境建立時,
需要從原始的Master上復制其private key和public key至第二個Master,覆蓋掉冗余Master自動生成的Key(只要啟動過第二個Master就會自動生成).

Master的private key默認存儲在/etc/salt/pki/master/master.perm,public key默認存儲在/etc/salt/pki/master.pub.
將key復制到新增的master上需要確保新增的master上並沒有minion連接進來。

2.Minion keys
Minion的keys需要每個Master都進行accept,可以使用salt-key手動接受Minion的key,也可以在Master間保持key目錄的同步。需要同步的目錄有:
●/etc/salt/pki/master/minions
●/etc/salt/pki/master/minions_pre
●/etc/salt/pki/master/minions_rejected

3.file_roots
file_roots的內容需要在Master間同步以保持一致。這里存放Salt State配置管理文件。推薦同步內容使用gifs backend,或者直接將file_roots存儲在共享存儲上。


4.pillar_roots
需保持Pillar數據一致。

5.Master Configuration
確保有關Master的配置選項在所有Master節點間是同步的。建議直接將原始的Master配置文件復制過去即可。

6.2.3 設置Minion
多Master在Minion節點,就是在Minion的配置文件中設置多個master列表即可。
vi /etc/salt/minion
master:
- 192.168.56.21
- 192.168.56.22

6.3 Salt Syndic

Syndic運行在一個master上,並且連接到另外一個Master(可稱為高級Master)。
然后Syndic Minion所連接的高級Master就可以直接連接到運行Syndic的Master上的Minion.

6.3.1 Syndic配置
Syndic沒有自己的配置文件,它是Salt Master的一個組件:
yum -y install salt-syndic
vi /etc/salt/master
syndic_master:192.168.56.22 #設置為高級Master的IP

/etc/init.d/salt-master restart
/etc/init.d/salt-syndic start

6.3.2 高級Master配置
高級Master需要使用order_masters參數來開啟:
yum install -y salt-master
vi /etc/salt/master
order_masters:True

6.3.3 Syndic測試
高級Master可以控制一群同時運行着“syndic和master”的節點,通過syndic將操作命令傳輸給受控Master,受控Master來完成對自己旗下Minion的管理,
並將結果傳回高級Master,從而實現高級Master對所有Minion的間接管理。

6.3.4 Syndic是如何工作的
Syndic本質上是一個特殊的Minion,其代碼位於minion.py中。
Syndic需要在本地運行Master,並將需要管理的Minions的Master指向syndic所在的主機。
Syndic工作流程;
●冒充Minion,建立與高級Master的連接,訂閱所有來自高級Master下發的任務
●接收高級Master下發的數據后,首先進行解密,解密完成后,將其扔到本地的Master接口上進行二次下發
●Syndic在進行二次下發之后,監聽本地Event接口,獲取所管理的Minions的返回
●將返回發送給高級Master


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM