saltstack系統中管理對象叫作Target,在master上能夠採用不一樣的Tatget去管理不一樣的minion。這些Target都是經過去管理和匹配Minion的ID來作一些集合。node
# salt -E '[a-z].*' test.ping #直接就是匹配字母開頭的minionweb
# salt -E 'a.*' test.ping #匹配a開頭的minion正則表達式
# salt -E '(a|z).*' test.ping #匹配a或者z開頭的minion,切記是開頭而不是包含。shell
# salt -L agent1.salt,zwidc_kvm_192.168.1.104 test.ping #同時讓兩個minion去執行,多minion之間用逗號隔開。apache
minions的Grains信息時在Minions服務啓動的時候彙總給Master的,Grains是saltstack組建中很是重要的,由於在配置部署的過程當中會常用它,Grains是saltstack記錄minion的一些靜態信息的組件,grains裏面記錄着每臺minion的一些經常使用屬性如CPU、內存等,能夠經過grains.item查看某臺minion的全部grains信息。vim
# salt -G 'os:CentOS' test.ping #讓minion端操做系統是CentOS去執行,固然也支持正則表達式的方式centos
# salt -G 'os:C*' test.ping #如匹配操做系統是C開頭的數組
# salt -G 'osmajorrelease:[1-9]' test.ping #匹配系統版本是數字的。安全
# cat /etc/salt/master |grep groups #如咱們定義了一個centosgroups組bash
nodegroups:
centosgroups: 'G@os:CentOS'
# salt -N centosgroups test.ping #就能夠指定讓某個組的minion去執行。
# salt -C 'G@os:CentOS and G@osrelease:6.4' test.ping #讓os是CentOS而且系統版本是6.4的去執行
# salt -C 'G@os:CentOS or G@osrelease:6.5' test.ping #讓os是CentOS或者系統版本是6.5的去執行
# salt -C 'G@os:CentOS and G@osrelease:6.4 and E@zwidc*' test.ping #讓zwidc的minion而且操做系統是CentOs6.4的去執行
# salt -S '192.168.1.0/24' test.ping #192.168.1.0/24是一個指定的CIDR網段,這裏CIDR匹配的IP地址是minion鏈接master4505端口的來源地址。
博文來自:www.51niux.com
Grains上面已經介紹過了,相似於facter。簡單的說就是把minion端在啓動的時候把自身的的各類屬性信息採集彙報給master端。
# salt '*' grains.ls #能夠查看有哪些屬性能夠查看,顯示的是屬性的名字,相似於os之類的。
# salt '*' grains.item os osrelease oscodename #知道了屬性的名稱,咱們就能夠查看屬性的值,這裏就是查看os,osrelease,oscodename這三個屬性的值,多屬性用空格隔開。
# salt '*' grains.items #這種就是將minion端屬性以及屬性的值全打印出來。
minion端的操做:
# cat /etc/salt/minion.d/position.conf #在默認的/etc/salt/minion.d目錄下面建立一個position.conf,這個文件的目的是來自定義服務器所在的位置的屬性信息。下面就是標準格式。
grains: #以grains開頭
roles: #設置一個屬性叫roles,下面若是多條就像下面同樣- value值,這裏的意思是標註服務器屬於什麼業務
- webserver
- memcache
deployment: bj-zw-datacenter #這裏是標註所在機房的位置
cabinet: B13 #標註所在機櫃的位置
cab_u: 14-15 #標註所在機櫃的U位
# service salt-minion restart #上面已經說了,grains信息是在minion端啓動的時候纔會發送,因此要重啓minion端。
master端的查看:
# salt 'agent1.salt' grains.ls #用這個查看會發現咱們自定義的哪幾個grains的屬性已經出現了。
# salt 'agent1.salt' grains.item roles deployment cabinet cab_u #查看一下對應的值
# salt 'agent1.salt' grains.append the_person 'chaishao' #經過grains.append方法爲agent1.salt機器添加了一個屬性,the_person使用人,後面跟的值是chaishao。
還可使用其餘的方法,如grains.setvals來定義多個屬性,或者還能夠刪除自定義的grains。這都是立馬生效並永久生效的。由於它修改的是minion端的/etc/salt/grains 文件。
Pillar是saltstack組件中很是重要的一個,是數據管理中心,常常配合states在大規模的配置管理工做中使用它,它的主要做用是存儲和定義配置管理中須要的一些數據。它的定義存儲格式跟grains相似,都是YAML格式。
下面的操做都是在master端的操做:
# mkdir /srv/pillar #這是master配置文件裏面#pillar_roots:默認指定的路徑。默認不存在須要手工建立。
# cat /srv/pillar/top.sls #top.sls是配置管理的入口文件,一切都是從這裏開始,這裏是默認位置
base: #top.sls 默認從 base 標籤開始解析執行,下一級是操做的目標,能夠經過正則,grain模塊,或分組名,來進行匹配,再下一級是要執行的state文件,不包換擴展名。
'*':
- pkgs
# cat /srv/pillar/pkgs.sls #一個簡單的根據minion端的grains信息,動態的設置apache軟件包對應的name名稱。
pkgs:
{% if grains['os_family'] == 'RedHat' %}
apache: httpd
{% elif grains['os_family'] == 'Debian' %}
apache: apache2
{% elif grains['os'] == 'Arch' %}
apache: apache
{% endif %}
# salt '*' pillar.item pkgs
有結果來看,pillar數據是在Salt master上生成的並被安全地分佈到minions上。Salt當定義pillar的時候,沒必要限制在sls文件,也能夠從外部資源得到數據,咱們能夠把Pillar數據。pillar中最強大的抽象之一就是將states參數化的能力。
States是SaltStack中的配置語言,在平常進行配置管理時須要編寫大量的States文件。如安裝軟件啊,更改配置啊等,就須要編寫states sls文件(描述狀態配置的文件)去描述和實現這些功能。編寫states sls文件通常是是YAML語法格式,也支持使用Python語言來編寫。
# salt 'agent1.salt' sys.list_state_modules #查看minion支持的全部states列表。
# salt 'agent1.salt' sys.list_state_functions file host #查看file和host的全部function,多模塊用空格隔開
# salt 'agent1.salt' sys.state_doc file #查看指定模塊的function的用法與例子,平常編寫states按照例子編寫即可。
# salt 'agent1.salt' sys.state_doc file.managed #查看file.managed的詳細用法與例子,這也是咱們常常用到的function。
# cat /srv/salt/test1.sls #編寫了一個簡單的file.managed的sls文件
/tmp/test1.conf: #state ID,全文件惟一,標籤訂義,若是模塊沒有跟-name,默認用的ID做爲-name
file.managed: #file state的manage function,狀態定義,指定引用哪一個模塊的方法函數。
- source: salt://files/test1.conf #文件來源(salt://默認表明了根目錄也就是states的工做目錄也就是/srv/salt。)
- user: root #文件的屬主,剩下的這些都是file.managed裏面的參數。
- group: root #文件的屬組
- mode: 0644 #文件的mode
# mkdir /srv/salt/files/ #由於咱們的source指定的是salt://files/,因此源目錄的絕對路徑應該是/srv/salt/files/下面的。
# touch /srv/salt/files/test1.conf #建立咱們要發送的文件,你也能夠寫點內容。
# salt '*' state.sls test1 #top.sls這個入口文件不是必須存在的,可是生產是確定要存在的,只是咱們這裏測試top.sls能夠暫時不存在。用state.sls來進行測試,state.sls默認的運行環境是base,state.sls並不讀取top.sls,因此state.sls須要單獨執行哪些sls的話,須要自定義。這裏咱們讓其執行test1.sls這個文件。
下面是測試截圖(下面是測試結果正確的截圖):
#若是你源文件沒有發生改變,再次執行的話,Comment會提示你這個文件是正確的。Changes:下面沒內容。Succeeded: 1,這就是區別,也就是不更新
博文來自:www.51niux.com
SLS(表明SaLt State文件)是Salt State系統的核心。SLS描述了系統的目標狀態,由格式簡單的數據構成。這常常被稱做配置管理。
由於咱們用YAML格式來編寫sls文件,因此掌握編寫技巧利於後面少出錯。
5.1.1 什麼是YAML?
YAML 語言(發音 /ˈjæməl/ )的設計目標,就是方便人類讀寫。它實質上是一種通用的數據串行化格式。語法很簡單,結構經過空格來展現,項目使用「-」來表明,鍵值對使用「:」分隔。
它的基本語法規則以下:
大小寫敏感,以「:」來分隔key和value。對象:鍵值對的集合,又稱爲映射(mapping)/ 哈希(hashes) / 字典(dictionary)。
使用固定的縮進風格表示層級關係。縮進時不容許使用Tab鍵,只容許使用空格,通常每一個縮進級別由兩個空格組成。
# 表示註釋,從這個字符一直到行尾,都會被解析器忽略。
想要表示列表項,使用一個短橫槓加一個空格。多個項目使用一樣的縮進級別做爲同一列表的一部分。列表能夠做爲一個鍵值對的value。
top.sls是配置管理的入口文件,這個很重要在生產中很重要,默認存放在/srv/salt/目錄。默認從base標籤開始解析執行,下一級是操做的目標也就是要對哪些主機進行操做,能夠經過正則、grain模塊或分組名等來進行匹配,而後再下一級是要執行的state文件(不包含.sls擴展名)。
# cat /srv/salt/top.sls #執行的test1仍是咱們上面編寫的那個簡單的test1.sls
base:
'agent*': #這裏定義了只有是註冊的時候是agent開頭的minion端的客戶端才能去執行test1裏面的配置管理
- test1 #這裏指的是同目錄下的一個test1.sls。只有這裏top.sls制定了,咱們在master執行:# salt '*' state.highstate test=True的時候纔會被引用到。
# cat /srv/salt/top.sls #若是你不是指定*全部來執行test1,只是想讓多個匹配規則去執行test1的話,能夠像我下面這樣寫。
base:
'agent*':
- test1
'zwidc*':
- test1
# cat /srv/salt/top.sls #可是上面那種寫法顯然要low一點,能夠- match: pcre,匹配正則表達式的方式來匹配對應的主機。
base:
‘(agent|zwidc)*’:
- match: pcre
- test1
# cat /srv/salt/top.sls
base:
centosgroups: #這裏就是咱們上面在master配置文件裏面定義的那個組名
- match: nodegroup #這句話是必需要有的,指定以組匹配
- test1
# cat /srv/salt/top.sls #同上-match: grain也是必需要帶的,指定讓其按照grain進行匹配,指定讓os是Centos的操做系統來執行。
base:
'os:CentOS':
- match: grain
- test1
# cat /srv/salt/top.sls #上面的grain模塊匹配可能知足不了咱們的匹配條件,我想要更加精確的讓全部Centos6.4的操做系統去執行,就是我下面的設置。
base:
'G@os:CentOS and G@osrelease:6.4':
- match: compound
- test1
# cat /srv/salt/top.sls
base:
'192.168.1.0/24':
- match: ipcidr
- test1
# salt '*' state.highstate #master將會指導全部的目標minions運行 state.highstate。當minion執行highstate,它將會下載top文件中匹配的內容,minion將表達式中匹配的內容下載、編譯、執行。一旦完成,minion將返回全部的動做執行結果和全部更改
# salt '*' state.highstate test=True #只是測試執行,相似於模擬,不會在minion真正執行,便於咱們編寫測試時使用。
SLS文件的擴展名.sls在state文件裏面將被省略,上面已經展現到了,如test1.sls在文件裏面就變爲了test1.
子目錄能夠更好的進行組織架構,每一個子目錄都由一個點來表示,如/srv/salt/init/dns.sls在調用時就能夠寫爲init.dns。
若是子目錄建立一個init.sls的文件,引用的時候僅指定該目錄便可,(例如test1/init.sls能夠簡稱爲test1)
若是一個目錄下同時存在test1sls和test1/init.sls,那麼test1/init.sls將被忽略,sls文件引用的test1將只引用test1.sls。
include:將別的SLS添加到當前文件中,因此能夠require或watch被引用的SLS中定義的內容,還能夠extend覆蓋其內容。include語句使得state能夠跨文件引用。使用include至關於把被引用的內容文件添加到自身。
extend:擴展被引用的SLS數據。不須要重頭寫新的SLS,能夠先直接include sls文件,而後在其基礎上增長或者覆蓋內容。
# cat /srv/salt/top.sls #咱們只引用了一個test1.sls文件
base:
'192.168.1.0/24':
- match: ipcidr
- test1
# cat /srv/salt/test1/init.sls
include: #格式就是include: 下面用- 空格 後面要加載的sls文件 - test1.test2 #這裏咱們雖然跟init.sls文件在同一個目錄下面,可是根目錄是/srv/salt,因此這裏要用test1.test2來表示test1目錄下面的test2.sls文件 /tmp/test1.conf: #剩下的就是test1的內容了。 file.managed: - source: salt://files/test1.conf - user: root - group: root - mode: 0644 - backup: minion
# cat /srv/salt/test1/test2.sls #寫了一個很簡單的發送文件的例子,用test2.conf和test1.conf區別開
/tmp/test2.conf: file.managed: - source: salt://files/test2.conf - user: root - group: root - mode: 0644 - backup: minion
# salt '*' state.highstate test=True #master端執行測試查看效果,從結果查看test2.sls確實被加載了:
覆蓋值的示例:
# cat /srv/salt/test1/init.sls
include:
- test1.test2
/tmp/test1.conf:
file.managed:
- source: salt://files/test1.conf
- user: root
- group: root
- mode: 0644
- backup: minion
extend: #extend: 下一行是test1.test2的ID號,因此/tmp/test2.conf這個文件是不能變的,這就是這個ID號是不能變的否則就找不到要去修改的標識了。 /tmp/test2.conf: #這個ID號是不能變的,是爲了告訴extend去修改哪一個ID下面的內容。 file.managed: #由於咱們配置的比較簡單,就file.managed這一個模塊函數,這裏就是指定要對哪一個模塊函數進行修改。 - source: salt://files/test3.conf #也就是file.managed下面的一些參數對應的值,這裏咱們將source從要下載test2.conf改成了下載test3.conf
# salt '*' state.highstate #master端執行讓minion去執行同步管理任務。從下方的能夠看出,客戶端/tmp/test2的文件內容發生了變化。
添加參數的示例:
# cat /srv/salt/test1/init.sls #其實就是test2.sls裏面沒有定義- watch,因此這裏就至關因而添加了。
include: - test1.test2 extend: /tmp/test2.conf: file.managed: - watch: - file: /tmp/test1.conf /tmp/test1.conf: file.managed: - source: salt://files/test1.conf - user: root - group: root - mode: 0644 - backup: minion
#Extend使得Salt的SLS更加靈活。爲何SLS可以作Extend呢?SLS中的文件僅僅是結構化的data而已,在處理SLS時,會將其中的內容解析成Python中的dict(固然這個dict中會嵌套dict和list)。修改test2 watch的內容,至關於往list裏面添加一個元素;修改test2.conf文件的下載路徑至關於修改dict中的某個key對應的值。在extending時,會附加加require/watch的內容,而不是覆蓋。
match : 配模某個模塊,好比 match: grain match: nodegroup
require: 依賴某個state,在運行此state前,先運行依賴的state,依賴能夠有多個
watch : 在某個state變化時運行此模塊,watch除具有require功能外,還增了關注狀態的功能。
order : 優先級比require和watch低,有order指定的state比沒有order指定的優先級高,假如一個state模塊內安裝多個服務,或者其餘依賴關係,可使用
require和require_in簡單示例:
# cat /srv/salt/test1/init.sls #這是require的示例,就是表示本身依賴於誰。
vim: #定義了第一個ID爲vim pkg: #而後引用的是pkg模塊 - installed #引用的是installed函數 - name: vim-enhanced #由於vim的軟件包名稱並不是vim,因此這裏要加上vim包組的名稱 /tmp/vimrc: file.managed: - source: salt://files/vimrc - require: #- require: 依賴於下面的ID操做,若是下面的ID操做了或者說要操做的內容已經存在了,本ID也就是/tmp/vimrc纔會去執行 - pkg: vim #依賴於id爲vim的pkg狀態,多依賴的話,下面照着這個來多行就能夠了。
#成功的測試就不截圖了,下面我估計講minion端的DNS解析關閉掉,而後執行查看一下錯誤截圖:
# cat /srv/salt/test1/init.sls #這是require_in的示例,表示誰依賴於我
vim:
pkg:
- installed
- name: vim-enhanced
- require_in: #表示下面的id表明的操做依賴於我是否能執行成功,在這裏就是表示我本次是否要安裝成功或者要安裝的軟件包組是否存在。 - file: /tmp/vimrc /tmp/vimrc: file.managed: - source: salt://files/vimrc
watch和watch_in的示例:
# cat /srv/salt/test1/init.sls #這是watch的示例,表示我檢測誰的變化,若是它變化執行了我就跟着執行,它要不執行我也不執行。
ntpd: #定義了一個ID是ntpd的配置規則 service.running: #這裏引用了service.running函數- enable: True默認就是這個,這裏就不加了。 - watch: #這裏它是監聽ID爲file: /etc/ntp.conf,若是下方的狀態沒有發生改變,那麼我這個重啓規則就不會執行,那麼就不會執行服務重啓操做。 - file: /etc/ntp.conf #也就至關於若是minion端的ntp.conf或者master端的salt://files/ntp.conf的文件沒有發生改變,也就不會發生文件下發操做,也就能夠理解爲若是沒有發生文件更改。 /etc/ntp.conf: file.managed: - source: salt://files/ntp.conf
下面是文件狀態沒有發生改變的截圖(一切相安無事):
下面是我更改了下master段的源文件,也就是ntp.conf,在其上面加了一行註釋,再次查看,ntpd服務重啓了:
# cat /srv/salt/test1/init.sls #這是watch_in的示例,表示我改變了執行了我就通知依賴於我變化的狀態規則讓他們也去執行。
ntpd:
service.running #主要是這裏要注意,上面的例子有冒號而這裏沒有,這是由於當不將任何參數傳遞給狀態時,冒號必須被省略。 /etc/ntp.conf: file.managed: - source: salt://files/ntp.conf - watch_in: #這就是若是執行了下發了ntp.conf操做,我就通知ID是ntpd的server狀態,讓其執行重啓服務操做。 - service: ntpd
state的執行是無序,那個無序是指執行咱們寫的那個sls是無序的,通常執行的時候會根據sls文件裏面狀態ID:寫的順序從上到下執行,正是由於那個無序,salt保證每次執行的順序是同樣的,就加入了state order。
# salt 'agent1.salt' state.show_highstate #就是查看狀態的執行順序從高到底排序結果
# salt 'agent1.salt' state.show_lowstate #查看狀態的執行順序從低到高排序結果
經過觀察會發現一個字段order,是order決定了狀態之間的前後執行順序,由於salt默認會自動設置order,從10000開始。能夠經過設置master配置文件參數添加一行:state_auto_order: False來關閉master的自動設置order。
Order的設定:
include 被include的文件Order靠前,先執行。
手動定義order字段,order的數字越小越先執行從1開始,-1是最後執行。
下面是order手工設置的一個小例子:
# cat /srv/salt/test1/init.sls #爲了演示效果,我打亂了狀態ID:在sls中的上下順序:
ntpd: service.running: - enable: True - order: 3 ntp: pkg.installed: - name: ntpdate - order: 1 /etc/ntp.conf: file.managed: - source: salt://files/ntp.conf - order: 2
# salt 'agent1.salt' state.highstate #執行一下查看一下效果(測試的時候能夠把order那一行註釋掉再次測試查看一下效果就頗有對比性。也能夠# salt 'agent1.salt' state.show_highstate直接查看):
博文來自:www.51niux.com
Jinja是基於Python的模板引擎,功能比較相似於PHP的Smarty。Salt默認使用yaml_jinja渲染器。yaml_jinja的流程是選用jinja2模板引擎處理SLS,而後再調用YAML解釋器。咱們須要瞭解一點Jinja語法知識,由於在配置管理中常常會用到,這也是salt能真正實現高度自動化配置的一個重要技能。
Jinja的使用分爲三個步驟:
File狀態使用template參數 - template: jinja。
模板文件裏面變量使用{{名稱}},好比{{PORT}}.
File狀態模塊裏面指定變量列表。
# cat /srv/salt/jinja1/init.sls #引用jinja靈活配置的小例子。
{% set iplist = grains['ipv4'] %} #首先{% set 變量名 = 給變量賦值 %},這種格式能夠設置一個格式。這裏咱們引用了grains獲取minion端的ipv4值的方式,得出來通常是一個列表也就是一個數組,127.0.0.1在第一位。 /tmp/minion.conf: file.managed: - source: salt://files/minion.conf.jinja #這裏若是你是要使用到jinja模式,文件裏面有好多變量的話,最好有個後綴,比較容易區分。 - template: jinja #這就是介紹裏面說的第一步,使用這個參數,說明本身使用的是jinja模板。 - defaults: #默認將值傳遞給模板 IP_ADDR: {{iplist[1]}} #IP_ADDR是minion.conf.jinja裏面定義的一個變量,後面的賦值用{{}}包起來,去iplist這個列表的第二個值。這個根據本身狀況再進行修改,我這就是爲了演示簡單寫了下。
# cat /srv/salt/files/minion.conf.jinja #這是模板文件,就寫了很短的一行,爲了掩飾效果。
ipaddr:{{IP_ADDR}}
# salt 'agent1.salt' state.highstate #master端執行一下,成功了,就不接圖了。下面咱們查看一下客戶端的配置文件裏面的IP是否是跟本機是一致的。
Jiaja變量使用很靈活的,下面大概總結一下:
變量使用單純的變量賦值(上面的例子也簡單的用了下)(除了模板引用之外sls文件也能夠直接引用,下面就是非模板的變量引用):
{% set keepalived_tar = 'keeplived-1.2.17.tar.gz' %} #用{%...%}符號定義變量 {% set keepalived_source = 'salt://modules/keepalived/files/keepalived-1.2.17.tar.gz' %} keepalived-install: file.managed: - name: /usr/local/src/{{ keepalived_tar }} #這裏用{{...}}引用變量賦值 - source: {{ keepalived_source }}
變量使用Grains(上面的例子也有列出):
IP_ADDR: {{grains['ipv4'][1]}} #上面的變量引用,能夠直接這樣寫的,更簡潔一點。
變量使用執行模板,也就是使用salt命令返回的值(由於grain只有再minion重啓的時候纔會將信息上交一份,要是在重啓以前有些配置發生了更改,不免匹配不許):
# cat /srv/salt/jinja1/init.sls
/tmp/minion.conf:
file.managed:
- source: salt://files/minion.conf.jinja
- template: jinja
- defaults:
IP_ADDR: {{salt['network.ip_addrs']}} #一個是獲取IP地址,salt表明是使用salt命令['要使用的funtion方法'] MAC: {{ salt['network.hw_addr']('eth0') }} #一個是獲取MAC地址,後面('eth0')是由於有的方法後面好跟參數,如network.hw_addr後面就須要跟接口名稱
# cat /srv/salt/files/minion.conf.jinja #注意模板這裏寫了幾個變量,sls文件裏面就要寫結果變量應該映射的值,否則會報錯說Jinja某個變量未定義
ipaddr:{{IP_ADDR}} mac:{{MAC}}
變量使用Pillar來定義變量的值(這個就是首先定義好了pillar,這裏來直接引用下就能夠了):
{{ pillar['apache']['PORT'] }}
Jinja還主要用來給狀態增長邏輯關係,如for循環,或者if判斷,也是常用到的。
salt,grains,pillar是salt中jinja裏面的三個特殊字典,salt是包含全部salt函數對象的字典,grains是包含minion上grains的字典,pillar是包含minion上pillar的字典。上面已經介紹瞭如何使用了。
if...elif...endif的示例:
# cat /srv/pillar/pkgs.sls
apache:
pkg.installed: #這是根據系統的不一樣,判斷安裝的軟件名稱。若是有變量就放到{{}}中 {% if grains['os_family'] == 'RedHat' %} #jinja中判斷,循環等標籤是放在{% %}中 - name: httpd {% elif grains['os_family'] == 'Debian' %} - name: apache2 {% elif grains['os'] == 'Arch' %} - name: apache {% endif %} #也會有結束標籤{% end** %}
#固然還支持:{% if %}...{% elif %}...{% else %}...{% endif %}之類的寫法。
for循環的示例:
{% set userlist = ['yunwei','cacti','www'] %} {% for user in userlist %} {{ user }}: user.present: - shell: /bin/bash - home: /home/{{ user }} {% endfor %}