saltstack學習筆記

   最近在學習saltstack,對照着官方的文檔學習的,官方文檔順序也有些問題,所以看得時候可能覺得順序安排有些不妥,那就繼續往前看,然後看第二遍就會好很多了。


一。target  就是指定你的命令或者模塊應用哪寫Minion上

1.globbing  默認

salt 'test*' test.ping

2.RE 正則

salt -E 'web1-(pro|devel)' test.ping

3.List 列表

salt -L '127.0.0.1, test*' test.ping

4.grains

salt -G 'os:CentOS' test.ping

查看所有grains鍵/值

salt 'test*' grains.items

查看所有grains項

salt 'test*' grains.ls

查看某個grains的值

salt 'test*' grains.item num_cpus


在top file中匹配grains

’node_type:web’:

  - match: grain         ##沒有s

  - webserver

 top file中使用jinja模板

 {% set self = grains['node_type'] %}

   - match: grain

- ` self `

5.nodegroups 其實就是對Minion分組

首先在master的配置文件中對其分組,我們推薦寫到/etc/salt/master.d/中一個獨立的配置文件中,比如nodegroup.conf

vim /etc/salt/master.d/nodegroup.conf   ##寫到master中也是這個格式,master.d中*.conf是默認動態加載的

nodegroups:

 test1: 'L@test1,test2 or test3*'

 test2: ‘G@os:CenOS or test2'


salt -N test1 test.ping                ##-N指定groupname


在top file中使用nodegroups


'test1':

 - match: nodegroup                   ##注意沒s

 - webserver


6.混合指定,就是將以上的混合起來用

 G Grains glob G@os:Ubuntu

 E PCRE Minion ID E@web\d+\.(dev|qa|prod)\.loc

 P Grains PCRE P@os:(RedHat|Fedora|CentOS)

 L List of minions [email protected],minion3.domain.com or bl*.domain.com

 I Pillar glob I@pdata:foobar

 S Subnet/IP address [email protected]/24 or [email protected]

 R Range cluster R@%foo.bar


 salt -C 'G@os:CentOS and [email protected],192.168.1.12' test.ping


 top file 指定:

 'webserver* and G:CentOS or [email protected],test1':

   - match: compound

- webserver


7.一次在n個minion上執行

  -b n

  --batch-size n

  示例:

  salt '*' -b 5 test.ping 5個5個的ping


二。使用gitfs做fileserver,用gitfs後,master會從git服務器取回文件緩存,minion不會直接聯繫git服務器

修改master配置文件/etc/salt/master(注:以後說master配置文件就是指該文件)


fileserver_backend:

 - git

gitfs_remotes:

 - git://github.com/saltstack/saltstack.git

 - git://github.com/example/test1.git      ##可以多個git

 - file:///root/td                         ##可以使用本地git


需要:python的模塊GitPython >= 0.3.0


saltstack的目錄結構

.

|-- bfile

|-- edit

|   `-- vim.sls

`-- top.sls


vim.sls

/tmp/a.txt:

 file.managed:

   - source: salt://bfile

ftp:

 pkg:

   - installed

也可以使用git下的子目錄作爲文件服務器根目錄

gitfs_root: somefolder/otherfolder


也可以混合使用git和本地磁盤作爲文件服務器

fileserver_backend:

 - roots

 - git

使用ssh協議的GitFS,私鑰爲~/.ssh/id_rsa

gitfs_remotes:

 - git+ssh://[email protected]/example/salt-states.git


三。遠程批量執行

格式:

 salt '<target>' <function> [argument]

注;

 function是salt帶的或自己寫的可執行模塊裏面的function,自帶的所有列表http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin

實例:

 salt '*' at.at 10.10am 'uptime'

 salt '*' test.ping


四。多Master實例

1.在另一臺機器上安裝salt-master

 yum -y install salt-master

2.將原來master上的master密鑰拷貝到新的master是一份

 scp /etc/salt/pki/master/master* newmaster:/etc/salt/pki/master/

3.啓動新的Master

 service salt-master start

4.修改minion配置文件/etc/salt/minion設置兩個master

 master:

   - master1

- master2

5.重啓minion

 service salt-minion restart

6.在新的master上接受所有key

 salt-key -L

 salt-key -A


注意:

 1.2個master並不會共享Minion keys,一個master刪除了一個key不會影響另一個

 2.不會自動同步File_roots,所以需要手動去維護,如果用git就沒問題了

 3.不會自動同步Pillar_Roots,所以需要手工去維護,也可以用git

 4.Master的配置文件也是獨立的



五。pillar的初體驗

簡介:

 Pillar在salt中是非常重要的組成部分,利用它可以完成很強大的功能,它可以指定一些信息到指定的minion上,不像grains一樣是分發到所有Minion上的,它保存的數據可以是動態的,Pillar以sls來寫的,格式是鍵值對

適用情景:

 1.比較敏感的數據,比如密碼,key等

 2.特殊數據到特定Minion上

 3.動態的內容

 4.其他數據類型


查看Minion的Pillar信息

 salt '*' pillar.items

查看某個Pillar值

 salt '*' pillar.item <key>      #只能看到頂級的

 或者

 salt '*' pillar.get <key>:<key> #可以取到更小粒度的


編寫pillar數據

1.指定pillar_roots,默認是/srv/pillar(可通過修改master配置文件修改),建立目錄

 mkdir /srv/pillar

 cd /srv/pillar

2.編輯一個pillar數據文件

 vim test1.sls

 name: 'salt'

 users:

   hadoop: 1000

redhat: 2000

ubuntu: 2001

3.建立top file指定minion到pillar數據文件

 vim top.sls

 base:

   '*':

     - test1

4.刷新Pillar數據

salt '*' saltutil.refresh_pillar

5.測試

 salt '*' pillar.get name

 salt '*' pillar.item name


在state中通過jinja使用pillar數據

vim /srv/salt/user.sls

 {% for user, uid in pillar.get(’users’, {}).items() %}  ##pillar.get('users',{})可用pillar['users']代替,前者在沒有得到值的情況下,賦默認值

 `user`:

   user.present:

     - uid: `uid`

 {% endfor %}


當然也可以不使用jinja模板

vim /srv/salt/user2.sls

{{ pillar.get('name','') }}:

 user.present:

   - uid: 2002

通過jinja模板配合grains指定pillar數據

/srv/pillar/pkg.sls


pkgs:

 {% if grains[’os_family’] == ’RedHat’ %}

 apache: httpd

 vim: vim-enhanced

 {% elif grains[’os_family’] == ’Debian’ %}

 apache: apache2

 vim: vim

 {% elif grains[’os’] == ’Arch’ %}

 apache: apache

 vim: vim

 {% endif %}




六。grains 就是服務器的一些靜態信息,這裏強調的是靜態,就是不會變的東西,比如說os是centos,如果不會變化,除非重新安裝系統

定義minion的grains可以寫在/etc/salt/minion中格式如下

grains:

 roles:

   - webserver

   - memcache

 deployment: datacenter4

 cabinet: 13

 cab_u: 14-15


或者卸載/etc/salt/grains中,格式如下

roles:

 - webserver

 - memcache

deployment: datacenter4

cabinet: 13

cab_u: 14-15


也可以在master中編寫grains的模塊,同步到minion中,用Python來寫很簡單的

1.在/srv/salt中建立_grains目錄

 mkdir /srv/salt/_grains

2.編寫grains文件,需要返回一個字典

 vim test1.py

 def hello():                      ##函數名字無所謂,應該是所有函數都會運行

   agrain = {}

   agrain['hello'] = 'saltstack'

return agrain                   ##返回這個字典

3.同步到各個minion中去

 salt '*' saltutil.sync_grains | salt '*' saltutil.sync_all | salt '*' state.highstate

4.驗證

 salt '*' grains.item hello


七。使用 salt state

使用salt state system是非常簡單的,它的核心是寫sls(SaLt State file)文件,sls文件默認格式是YAML格式(以後會支持XML),並默認使用jinja模板,YAML與XML類似,是一種簡單的適合用來傳輸數據的格式,而jinja是根據django的模板語言發展而來的語言,簡單並強大,支持for if 等循環判斷。salt state主要用來描述系統,軟性,服務,配置文件應該出於的狀態,常常被稱爲配置管理!

通常state,pillar,top file會用sls文件來編寫。state文件默認是放在/srv/salt中,它與你的master配置文件中的file_roots設置有關


示例:

apache.sls文件內容 ##/srv/salt/apahce.sls,以後沒有用絕對路徑意思就是在/srv/salt下


apache:            ##state ID,全文件唯一,如果模塊沒跟-name默認用的ID作爲-name

 pkg:             ##模塊

   - installed    ##函數

  #- name: apache ##函數參數,可以省略

 service:         ##模塊

   - running      ##函數

  #- name: apache ##函數參數,這個是省略的,也可以寫上

   - require:     ##依賴系統

     - pkg: apache  ##表示依賴id爲apache的pkg狀態


YAML通過用縮進來分層,且'-' ':'等後面必須跟一個空格,YAML與python數據類型對比


a:                                

 b: test           vs               a = {'b': 'test', 'c': 'ok'}           字典

 c: ok


a:

 - b

 - c               vs               a = ['b', 'c', 'd']                    列表

 - d


下面來解釋上面示例的意思:

聲明一個叫apache的狀態id,該id可以隨意,最好能表示一定意思,pkg代表的是pkg模塊,installed是pkg模塊下的一個函數,描述的是狀態,該函數表示apache是否部署,返回值爲True或者False,爲真時,表示狀態OK,否則會去滿足該狀態(下載安裝apache),如果滿足不了會提示error,在該模塊上面省略了參數-name: apache,因爲ID爲apache,這些參數是模塊函數需要的(可以去查看源碼),,service是指的service模塊,這個模塊下主要是描述service狀態的函數,running狀態函數表示apache在運行,省略-name不在表述,-require表示依賴系統,依賴系統是state system的重要組成部分,在該處描述了apache服務的運行需要依賴apache軟件的部署,這裏就要牽涉到sls文件的執行,sls文件在salt中執行時無序(如果沒有指定順序,後面會講到order),假如先執行了service這個狀態,它發現依賴pkg包的安裝,會去先驗證pkg的狀態有沒有滿足,如果沒有依賴關係的話,我們可以想象,如果沒有安裝apache,apache 的service肯定運行會失敗的,我們來看看怎麼執行這個sls文件:


# salt '*' state.sls apache   ##在命令行裏這樣執行就ok了,.sls不要寫,如果在目錄下,將目錄與文件用'.'隔開,如: httpd/apache.sls --> httpd.apache

或者

# salt '*' state.highstate    ##這需要我們配置top file執定哪個minion應用哪個狀態文件


top.sls內容


base:

 '*':

   - apache


下面我們繼續看一些比較複雜的:


ssh/init.sls文件內容


openssh-client:

 pkg.installed

/etc/ssh/ssh_config:

 file.managed:

   - user: root

- group: root

- mode 644

- source: salt://ssh/ssh_config

- require:

 - pkg: openssh-client

ssh/server.sls文件內容


include:

 - ssh


openssh-server:

 pkg.installed


sshd:

 service.running:

   - require:

 - pkg: openssh-client

 - pkg: openssh-server

 - file: /etc/ssh/banner

 - file: /etc/ssh/sshd_config


/etc/ssh/sshd_config:

 file.managed:

   - user: root

- group: root

- mode: 644

- source: salt://ssh/sshd_config

- require:

 - pkg: openssh-server


/etc/ssh/banner:

 file:

   - managed

- user: root

- group: root

- mode: 644

- source: salt://ssh/banner

- require:

 - pkg: openssh-server


兩個文件的內容,主要是描述ssh服務的狀態的,有沒有覺得YAML看起來確實是比較好看的,有層次感,如果用XML的話可能就不是那麼賞心悅目了,我們從開頭開始說起,ssh/init.sls,學過Python的都知道目錄下面的init文件是特殊文件,它怎麼特殊呢,它特殊在當我們應用目錄時會應用該文件的內容,如我們執行 salt '*' state.sls ssh時應用的就是init.sls文件,明白了嗎?再看裏面的內容,前兩行我們已經看過了,是描述某個rpm包有沒有安裝的,第三行是ID,也可以用來表示-name,以省略-name,file.managed是file模塊與函數managed的快捷寫法,看server.sls下最後就知道了,managed它描述了某個文件的狀態,後面跟的是managed的參數,user,group,mode你們一看就知道什麼意思了,關於這個source是指從哪下載源文件,salt://ssh/sshd_config是指的從salt的文件服務器裏面下載,salt文件服務器其實就是file_roots默認/srv/salt/明白了嗎,所以salt://ssh/sshd_config指的就是 /srv/salt/ssh/sshd_config,出來用salt的文件服務器,也可以用http,ftp服務器。- require是依賴系統不表,以後會詳細說它的。再往下是server.sls文件,include表示包含意思,就是把ssh/init.sls直接包含進來,省的複製粘貼了,爲什麼include的不是ssh/init你懂了嗎?下面的相信你能看懂了。


這時你會看到/srv/salt的目錄樹是:


ssh/init.sls

ssh/server.sls

ssh/banner

ssh/ssh_config

ssh/sshd_config


下面再來看一個官方樣例:

ssh/custom-server.sls 文件內容


include:

 - ssh.server

extend:

 /etc/ssh/banner:

   file:

 - source: salt://ssh/custom-banner


python/mod_python.sls文件內容


include:

 - apache


extend:

 apache:

   service:

 - watch:

   - pkg: mod_python


其實我就想讓你看看extend的用法而已,嘿嘿,首先我們include的別的文件,但是裏面的內容並不是全部符合我們的要求,這時我們就需要用extend來重寫部分內容,特殊的是依賴關係都是追加。custom-server.sls文件意思是包含ssh/server.sls,擴展/etc/ssh/banner,重新其source而其它的如user,group等不變,與include一致。 mode_python.sls文件意思是把apache.sls包含進來,想apache-service是追加了依賴關係(watch也是依賴系統的函數).


八。關於渲染器render system

我們上面也提過salt默認的渲染器是yaml_jinja,salt處理我們的sls文件時,會先把文件用jinja2處理,然後傳給ymal處理器在處理,然後生成的是salt需要的python數據類型。除了yaml_jinja還有yaml_mako,yaml_wempy,py,pydsl,我比較感興趣的就是yaml_jinja,還有py,yaml_jinja是默認的,而py是用純python來寫的。下面來看個樣例吧,


apache/init.sls文件內容


apache:

 pkg:installed:

   {% if grains['os'] == 'RedHat' %}

- name: httpd

{% endif %}

 service.running:

   {% if grains['os'] == 'Redhat' %}

- name: httpd

{% endif %}

- watch:

 - pkg: apache


這個樣例很簡單,就是加了個判斷,如果Minion的grains的os是RedHat那麼apache的包名是httpd,默認是apache,我們知道在別的Linux發行版上,如ubuntu,suse他們的apache的包名就是叫apache,而在redhat繫上則叫httpd,所以纔有了這個判斷寫法,下面的service也是如此。我們着重說語法,jinja中判斷,循環等標籤是放在{%  %}中的,通常也會有結束標籤{% end** %},而變量是放在 ` `中的,salt,grains,pillar是salt中jinja裏面的三個特殊字典,salt是包含所有salt函數對象的字典,grains是包含minion上grains的字典,pillar是包含minion上pillar的字典。


示例:for

user/init.sls文件內容


{% set users = ['jerry','tom','gaga'] %}

{% for user in users %}

` user `:

 user.present:

   - shell: /bin/bash

   - home: /home/` user `

{% endfor %}


示例;salt字典

user/init.sls文件內容


{% if salt['cmd.run']('uname -i') == 'x86_64' %}

hadoop:

 user.present:

   - shell: /bin/bash

   - home: /home/hadoop

{% elif salt['cmd.run']('uname -i') == 'i386' %}

openstack:

 user.present:

   - shell: /bin/bash

- home: /home/openstack

{% else %}

django:

 user.present:

   - shell: /sbin/nologin

{% endif %}


py渲染器

說明:py渲染器是用純python寫的sls文件,它返回的數據與yaml_jinja經過jinja處理經過yaml處理後的數據類似 ,用其他渲染器需要在sls文件頭行聲明用的渲染器類型,#!py就是聲明用的py渲染器,py中可用的變量有__salt__,__grains__,__pillar__,__opts__,__env__,__sls__,前三個分別對應jinja裏的salt,grains,pillar,__opts__是minion的配置文件的字典,__env__對應的是環境如base,__sls__對應的是sls的文件名


示例:

user/init.sls


#!py


import os

def run():

   '''add user hadoop'''

platform = os.popen('uname -a').read().strip()

if platform == 'x86_64':

   return {'hadoop': {'user': ['present',{'shell': '/bin/bash'}, {'home': '/home/hadoop'}]}}

elif platform == 'i386':

       return {'openstack': {'user': ['present', {'shell': '/bin/bash'}, {'home': '/home/openstack'}]}}

else:

   return {'django': {'user': ['present', {'shell': '/sbin/nologin'}]}}


說明: 首行聲明瞭使用py作爲渲染器,導入了os模塊,聲明run函數,py渲染sls文件是從run函數開始的,其它的就是python的語法了,注意的是return的數據結構{ID: {module: [func, arg1,arg2,...,]}} 或 {ID: {module.func: [arg1,arg2,..,]}} 。表示的內容與“示例;salt字典”表達的相同


九。state的執行順序  

以前我們說過,state的執行時無序,那個無序是指執行我們寫的那個sls是無序的,正是因爲那個無序,salt保證每次執行的順序是一樣的,就加入了state order,在說它之前看看High Data(高級數據?)和Low Data(低級數據?),高級數據我理解的就是我們編寫sls文件的數據,低級數據就是經過render和parser編譯過的數據。


查看highdata

salt ’*’ state.show_highstate

查看lowdata

salt ’*’ state.show_lowstate


通過查看lowdata我們發現裏面有一個字段order,因爲salt默認會自動設置order,從10000開始。可以通過設置master配置文件參數state_auto_order: False來關閉


Order的設定:

1.include 被include的文件Order靠前,先執行

2.手動定義order字段,如

  apache:

    pkg:

  - installed

  - order: 1

 order的數字越小越先執行從1開始,-1是最後執行

3.依賴關係系統


十。依賴關係系統requisite system

前面我們已經用過了依賴關係系統,就是定義狀態與狀態之間的依賴關係的,經常遇到的依賴系統的函數有'require'和'watch'和它們的變種'require_in','watch_in',require和watch有什麼區別嗎?

1.不是所有的state都支持watch,比較常用的是service

2.watch定義的依賴條件發生變化時會執行一些動作,如當配置文件改變時,service會重啓


示例:

apache/init.sls文件內容


/etc/httpd/httpd.conf:

 file:

   - managed

- source: salt://httpd/httpd.conf

httpd:

 pkg:

   - installed

 service:

   - running

   - require:

     - pkg: httpd

   - watch:

     - file: /etc/httpd/httpd.conf            ##當httpd.conf改變時,重啓httpd服務

require與require_in, watch與watch_in

require,watch是指依賴,require_in,watch_in是指被依賴

a reuire b 那麼就是b require_in a

a watch b  那麼就是b watch_in a


示例:

apache/init.sls文件內容


/etc/httpd/httpd.conf:

 file:

   - managed

- source: salt://httpd/httpd.conf

- watch_in:

 - service: httpd

httpd:

 pkg:

   - installed

- require_in:

 - service: httpd

 service:

   - running


十一。salt state環境

針對不用環境,應用不同的state的file,salt支持多環境,比如開發,測試,生產等環境,我們通過修改Master配置文件對不同的環境應用不同的目錄!


file_roots:

 base:

   - /srv/salt/prod   ##生產環境

 qa:

   - /srv/salt/qa     ##測試環境,如果沒發現去prod裏面找

- /srv/salt/prod

 dev:

   - /srv/salt/dev    ##開發環境,如果找不到,先去qa裏找,如果找不到再去prod裏面找

- /srv/salt/qa

- /srv/salt/prod

/srv/salt/prod/top.sls文件內容

base:

 'web*prod*':

   - webserver.foobarcom

qa:

 'web*qa*':

   - webserver.foobarcom

dev:

 'web*dev':

   - webserver.foobarcom

pillar的目錄與file_roots無關,所以Pillar的目錄默認還是/srv/salt,pillar只是Minion的一些信息,不會對系統有什麼改變,所以不需要區分環境,通常base即可。

/srv/pillar/top.sls文件內容


base:

 'web*prod*':

   - webserver.prod

 'web*qa*':

   - webserver.qa

 'web*dev*':

   - webserver.dev


/srv/pillar/webserver/prod.sls文件內容


webserver_role: prod


/srv/pillar/webserver/qa.sls文件內容


webserver_role: qa


/srv/pillar/webserver/dev文件內容


webserver_root: dev


最後sls文件/srv/salt/prod/webserver/foobarcom.sls(該文件會被所有環境訪問到)的內容:

{% if pillar.get('webserver_role', '') %}

/var/www/foobarcom:

 file.recurse:

   - source: salt://webserver/src/foobarcom

- env: {{ pillar['webserver_role'] }}

- user: www

- group: www

- dir_mode: 755

- file_mode: 644

{% endif %}


開發完成後,應用sls文件

1.現在開發環境

salt -I 'webserver_role:dev' state.sls webserver.foobarcom


十一。關於salt簡介,安裝和基本配置

說明:salt是一個異構平臺基礎設置管理工具(雖然我們通常只用在Linux上),使用輕量級的通訊器ZMQ,用Python寫成的批量管理工具,完全開源,遵守Apache2協議,與Puppet,Chef功能類似,有一個強大的遠程執行命令引擎,也有一個強大的配置管理系統,通常叫做Salt State System。


安裝:

1.安裝epel源

 For RHEL 5:

   rpm -Uvh http://mirror.pnl.gov/epel/5/i386/epel-release-5-4.noarch.rpm

 For RHEL 6:

   rpm -Uvh http://ftp.linux.ncsu.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm

2.安裝salt-master端,也就是服務端

 yum -y install salt-master

3.安裝salt-minion端,也就是client端

 yum -y install salt-minion


配置:

通常學習環境,master用默認配置就好,修改Minion配置文件/etc/salt/minion

master: master_ip或master_FQDN     ##註明master的ip或者域名

id: minion_id                      ##取一個獨一無二的minion名字,以方便辨認


啓動:

service salt-master start

service salt-minion start


master接受minion的key:

salt-key -L ##查看所有minion_key

salt-key -a 'key-name' ##接受該key

或者salt-key -A        ##接受所有key


測試:

 salt '*' test.ping   ##查看在線minion

 salt '*' pkg.install ftp  ##所有Minion安裝ftp

 說明:

 1. '*' 代表的是target是指在那些minion上操作

 2. ’test' ,'pkg'是一個執行模塊,所有的執行模塊見http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin

 3. 'ping','install'是執行模塊下面的函數,同樣參加上述鏈接查看幫助

 4. 'ftp' 是函數的參數(arg),有的函數需要參數,有的不需要


幫助:

   salt '*' sys.doc     ##查看所有執行模塊的doc

salt '*' sys.doc test   ##查看test模塊的幫助

salt '*' sys.doc test.ping ##查看test.ping函數的幫助

遇到弄不清楚的,儘管sys.doc吧

執行命令:

   salt '*' cmd.run 'uptime'  ##在所有機器上執行命令uptime

salt '*' cmd.run '--reboot--'  ##這類命令很危險,請不要嘗試,請想辦法禁止

基本原理:

 salt區分server和client,server端就是salt的master,client端就是minion,minion與master之間通過ZeroMQ消息隊列通信,minion上線後先與maste端聯繫,把自己的pub key發過去,這時master端通過salt-key -L命令就會看到minion的key,接受該minion-key後,也就是master與minion已經互信,master可以發送任何指令讓minion執行了,salt有很多可執行模塊,比如說cmd模塊,在安裝minion的時候已經自帶了,它們通常位於你的python庫中,locate salt | grep /usr/ 可以看到salt自帶的所有東西。這些模塊是python寫成的文件,裏面會有好多函數,如cmd.run,當我們執行salt '*’ cmd.run 'uptime'的時候,master下發任務匹配到的minion上去,minion執行模塊函數,並返回結果。master監聽4505和4506端口,4505對應的是ZMQ的PUB system,用來發送消息,4506對應的是REP system是來接受消息的。


十二。salt常用命令

1.salt 該命令執行salt的執行模塊,通常在master端運行,也是我們最常用到的命令

 salt [options] '<target>' <function> [arguments]

 如: salt '*' test.ping

2.salt-run 該命令執行runner(salt帶的或者自定義的,runner以後會講),通常在master端執行,比如經常用到的manage

 salt-run [options] [runner.func]

 salt-run manage.status   ##查看所有minion狀態

 salt-run manage.down     ##查看所有沒在線minion

 salt-run manged.up       ##查看所有在線minion

3.salt-key 密鑰管理,通常在master端執行

 salt-key [options]

 salt-key -L              ##查看所有minion-key

 salt-key -a <key-name>   ##接受某個minion-key

 salt-key -d <key-name>   ##刪除某個minion-key

 salt-key -A              ##接受所有的minion-key

 salt-key -D              ##刪除所有的minion-key

4.salt-call 該命令通常在minion上執行,minion自己執行可執行模塊,不是通過master下發job

 salt-call [options] <function> [arguments]

 salt-call test.ping           ##自己執行test.ping命令

 salt-call cmd.run 'ifconfig'  ##自己執行cmd.run函數

5.salt-cp  分發文件到minion上,不支持目錄分發,通常在master運行

 salt-cp [options] '<target>' SOURCE DEST

 salt-cp '*' testfile.html /tmp

 salt-cp 'test*' index.html /tmp/a.html

6.salt-ssh 0.17.1版本加入的salt-ssh,以後會講

7.salt-master master運行命令

 salt-master [options]

 salt-master            ##前臺運行master

 salt-master -d         ##後臺運行master

 salt-master -l debug   ##前臺debug輸出

8.salt-minion minion運行命令

 salt-minion [options]

 salt-minion            ##前臺運行

 salt-minion -d         ##後臺運行

 salt-minion -l debug   ##前臺debug輸出

9.salt-syndic  syndic是salt的代理,以後會說到


十三。普通用戶執行salt

普通用戶執行salt兩種方案:1,salt ACL   2.salt external_auth

1.ACL

 1) 設置master配置文件

     client_acl:

   monitor:

     - test*:

   - test.*

dev:

 - service.*

sa:

 - .*

 2) 重啓Master

     # service salt-master restart

 3) 目錄和文件權限

     # chmod +r /etc/salt/master

 # chmod +x /var/run/salt

 # chmod +x /var/cache/salt

 4) 測試

     # su - monitor

 # salt 'test*' test.ping

 # exit; su - sa

 # salt '*' test.ping

 # salt '*' cmd.run 'uptime'

 # exit;

2.external_auth

 1) 修改master配置文件

     external_auth:

   pam:

 monitor:

   - 'test*':

 - test.*

 sa:

   - .*

 2) 3)與ACL相同

 4) 測試

     # salt -a pam 'test*' test.ping    ##會提示輸入賬號密碼,所以external_auth與當前用戶無關

   username: monitor

       password:

 # su - monitor

 # salt -a pam '*' cmd.run 'uptime'

   username: sa

password:

 5) 使用Token不必每次都輸入賬號密碼,使用external_auth每次都是需要密碼的,這樣多麻煩,這裏引入了Token,它會保存一串字符到在當前用戶家目錄下.salt_token中,在有效時間內使用external_auth是不需要輸入密碼的,默認時間12hour,可以通過master配置文件修改

     # salt -T -a pam '*' test.ping

   username: sa

password:

 # salt -a pam '*' test.ping    #不會提示輸入密碼了

十四。salt schedule

salt的schedule是什麼東西?schedule是salt中的crontab,就是週期性執行一些函數,需要注意的是在minion上執行的函數是salt的可執行模塊裏的函數,在master上執行的是runner模塊的函數,下面看看如何設置:

master是修改master配置文件/etc/salt/master:

schedule:

 overstate:                    ##這個是ID,可以隨意起,全文件唯一

   function: state.over        ##對於master,function就是runner

   seconds: 35                 ##間隔秒數

   minutes: 30                 ##間隔分數

   hours: 3                    ##間隔小時數

這時每隔3小時30分35秒,master就會運行一個state.over這個runner


minion的schedule定義有兩種方式

1.通過修改minion的配置文件,這種方式需要修改所有Minion的配置文件略麻煩

schedule:

 highstate:

   function: state.highstate

seconds: 30

minutes: 5

hours: 1


2.爲Minion指定pillar

/srv/pillar/schedule.sls文件內容

schedule:

 highstate:

   function: state.highstate

seconds: 30

minutes: 5

hours: 1

通過top file指定到Minion

/srv/pillar/top.sls文件內容

base:

 *:

   - schedule


十五。YAML語法風格

1.空格和Tabs

 在YAML中不要使用Tab

2.縮進

 YAML推薦縮進爲2個空格,':','-'後面縮進1個空格再寫

3.數字會解析成數字

 如mode: 0644會解析成mode: 644,可用'括住防止mode: '0644'此情況

4.YAML不允許雙簡寫

 vim:

   pkg.installed   ##第一個簡寫,單一個簡寫沒問題

user.present    ##第二個簡寫,加上它是不支持的

 不要偷懶寫成下面這樣吧。

 vim:

   pkg:          

 - installed

user:

 - present

5.YAML只支持ASCII

 其它字符集最好不要使用,如果非要使用用以下格式:

 - micro: '\u00b5'

6.下劃線_將會被刪除

 date: 2013_05_13  --> date: 20130513

 通過'括住防止出現該問題

 date: '2013_05_13'  

十六。salt事件系統與反應系統 event and reacter system

我們知道Master與Minion是基於ZMQ通信的,他們通信我們看來是消息隊列,對它們來說這些消息就是一些事件,什麼事件應該做什麼,是salt基本已經預設好了。我們學習它的事件系統來完成一些自定義的行爲,後面的反應系統就是基於事件系統的。一條消息其實就是一個事件,事件通常是一個字典數據,這個字典數據通常包含tag,這個tag是用來區分用途過濾消息的,詳見綠大-https://groups.google.com/forum/#!topic/saltstack-users-cn/wXVE4ydnnzc ,讓我們來看看這些事件。


捕捉事件(listen event)

1.下載官方給的事件捕捉程序eventlisten

https://github.com/saltstack/salt/blob/develop/tests/eventlisten.py

打開網址,複製下載,不要直接wget

2.運行該程序

Master: python2.6 eventlisten.py                         ##捕捉master端的event直接運行即可

Minion: python2.6 eventlisten.py -n minion <minion-id>   ##捕捉minion端的需要額外參數,minion-id是該Minion的id


發送事件(fire event)

Master發給minion

salt '*' event.fire "{'data': 'some message'}" "tag"     ##前面必須是字符串包住的字典,後面是tag,如果你的minion在監聽event,你會看到這條event的


Minion發給minion

salt-call event.fire_master 'some message' 'tag'  ##前面數據類型沒有要求,後面是tag,去master那看看收到了沒有


Minion發給自己

salt-call event.fire "{'data': 'some message'}" 'tag' ##前面必須是字符串包住的字典,後面是tag



用code來捕捉,併發送event


捕捉事件

Maste:

# python2.6

>>> import salt.utils.event

>>> event = salt.utils.event.SaltEvent('master', '/var/run/salt/master')

##master表明是在master端監聽,/var/run/salt/master是你master的sock_dir

>>> data = event.get_event()

>>> print(data)       ##查看內容

>>> data = event.get_event(wait=10, tag='auth') ##wait是指timeout時間,默認5s,用tag來過濾事件,可省略

>>> print(data)                

>>> for data in event.iter_events(tag='auth'):  ##用迭代器一直查看事件

>>>     print(data)

Minion:

#python2.6

>>> import salt.utils.event

>>> event = salt.utils.event.SaltEvent('minion', '/var/run/salt/minion',id='minion_id')

##minion代表是在minion端監聽,/var/run/salt/minion是minion端的sock_dir,minion_id是該Minion的id

>>> data = event.get_event()

>>> print(data)

>>> for data in event.iter_events(tag='auth'):  ##用迭代器一直查看事件

>>>     print(data)


-----------------先這樣吧

發送事件:

Master:

>>> import salt.utils.event

>>> event = salt.utils.event.SaltEvent('master', '/var/run/salt/minion')

>>> event.fire_event({'hello': 'world'}, 'hello')

-----------------先這樣


反應系統(reacter system)

反應系統是基於事件系統的,它的作用是當master收到來自minion的特殊事件後就觸發某些動作,比如minion上線後發送一個init事件,master收到後,對其應用init的狀態文件,minion沒有反應系統,事情就是這樣的。


配置reactor

1.修改master配置文件或者在/etc/salt/master.d/中建立reactor.conf,內容

reactor:

 - 'testtag':                    ##接收到的tag

   - /srv/reactor/start.sls

- /srv/reactor/monitor.sls

 - 'test1*tag':                  ##接收到的tag,支持通配符

   - /srv/reactor/other.sls

2.建立reactor響應sls文件

/srv/reacter/start.sls文件內容


{% if data['id'] == 'mysql1' %}

delete_file:

 cmd.cmd.run:

   - tgt: 'G@os:CentOS'

- expr_form: compound

- arg:

 - rm -rf /tmp/*

{% endif %}


/srv/reactor/other.sls文件內容


{% if data['data']['state'] == 'refresh' %}

overstate_run:

 runner.state.over

{% endif %}


下面來解釋一下這兩個文件,reacter的sls文件是支持jinja的,所以第一行是通過jinja來判斷,reacter的sls支持兩個變量data和tag, data是接受事件的那個字典,tag就是事件的tag,所以第一行的判斷就很好理解了,第二行是id,可以隨意起,第三行是要運行的執行模塊或者runner,如果是執行模塊,以cmd.開始,如果是runner則以runner.開始,可執行模塊執行需要target,所以- tat:後面跟的就是可執行模塊的target,- expr_form指的target的匹配方式,- arg是隻執行模塊函數的參數,runner一般不需要這些。所以第一個示例相當於執行了salt -C 'G@mysql1' cmd.run 'rm -rf /tmp/*' 第二個相當於執行了 salt-run state.over


練習:

自己寫個reacter在讓minion觸發一個event測試一下吧




十七。salt Mine

salt的用的詞都太高明,像Grains,Pillar,Mine真心沒一個合適的詞去翻譯,Mine是做什麼的呢?Mine的作用是在靜態數據和動態數據建立起一座橋樑(官方文檔如是說),Mine從minon收集數據然後發送給Master,並緩存在Master端,所有Minion都可以輕易的共享到,Master通常會維護比較新的數據,如果需要維護長期數據,就要考慮retruner或外部的工作緩存了。 mine的出現是用來解決一定問題的. 在Salt的網絡體系中,各個minion是毫無關係,相互獨立的. 但是在實際應用中,minion之間其實是有一定關聯的,比如一臺機器需要獲取到另一臺機器的一些信息或者執行一些命令. 後來Salt加入了peer系統(http://docs.saltstack.com/ref/peer.html)使其成爲可能. 但是peer系統每次使用的時候都會重新執行一遍, 顯然很多不常變化的信息重複執行效率較低,性能開銷較大. 所以就有了後來的mine(peer和mine的關係是我杜撰出來的,如有雷同,純屬巧合). mine系統存儲在master端, minion想獲取的時候, 通過mine.get獲取下就可以了,簡單方便 by綠肥


修改minion配置文件,配置Mine

mine_functions:

 network.interfaces: []

 test.ping: []

 mine_interval: 1


重啓Minion,在master端測試

salt '*' mine_get '*' network.interfaces

salt '*' mine_get '*' test.ping

salt 'test1' mine_get '*' test.ping    ##查看test1上能得到mine數據


十八。salt ssh

從0.17.0開始salt加入salt ssh,salt ssh不需要在客戶端安裝salt-minion包了,是通過ssh協議來完成運城命令執行,狀態管理等任務的。它是作爲master-minion形式的補充出現的,原理是有一個花名冊的文件,裏面記錄了各個minion的信息,ip,賬號,密碼,等,需要遠程執行命令時,直接通過ssh來執行,速度與master-minion形式慢很多。


使用:

1.配置/etc/salt/roster格式如下

test1:

 host: 192.168.1.133

 user: salt

 passwd: redhat

 sudo: True

 port: 22

 timeout: 5

test2:

 host: 192.168.1.134

 user: root

 passwd: redhat

test3:

 host: 192.168.1.135

 user: sa

 sudo: True

 說明: test1我們定義了所有常見的選項,test2我們用了超級用戶,使用賬號密碼,test3我們使用普通用戶,沒有寫密碼,就是通過key來認證了,並且以sudo方式執行的,需要注意的是1.key認證用的是/etc/salt/pki/master/ssh/目錄下的密鑰。2.如果普通用戶的話,需要有sudo權限,因爲一些功能,包括test.ping都需要sudo權限。


測試:

 salt-ssh '*' test.ping

 salt-ssh '*' -r 'ls /'   ##執行shell命令

 salt-ssh '*' cmd.run 'ls /' ##用模塊來執行也是可以的

 salt-ssh '*' state.sls   ##執行狀態,state.sls在0.71.0中還存在bug,0.72.0中已解決


十九。Returners

默認所有minion返回的值都會發送到master端,我們可以看到,returner就是讓Minion把返回的值發給其它地方,如redis,MySQL,或者一個文本

下面我們來自定義一個returner:

1.建立自定義returner

# mkdir -p /srv/salt/_returners;

# vim mysql.py  ##就用官方給的例子吧,修改其中mysql的Host,user和pass

 內容見https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py

2.建立需要的數據庫

 見https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py註釋裏的見表語句

3.授權其他主機用戶可寫該表

 > grant all on salt.* to 'user_in_returner'@'%' identified by 'passwd_in_returner';

4.同步

# salt '*' saltutil.sync_all      ##同步到minion上去

5.測試

# salt '*' test.ping --return mysql    ##數據返回到mysql上去,打開mysql查看


二十。擴展salt

通過自定義各個模塊來擴展salt,常見自定義模塊有:

1.可執行模塊 Execution Modules

 如我們常用的cmd.run , test.ping這樣的可執行模塊

2.Grains

 擴展grains,grains是一些靜態信息,可能好多我們需要的沒有,我們可以通過編寫grains模塊自定義grains

3.狀態模塊 State Module

 如我們常用的pkg.install,file.managed

4.Returners

 我們可以自定義returner,將返回的數據發送到其他存儲,只要符合固定的格式就行了

5.Runner

 Runner是在master端快速執行的模塊,自定義很方便


135.97


二十一。自定義可執行模塊

所有可執行module見https://github.com/saltstack/salt/tree/develop/salt/modules,或http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin

1.建立自定義模塊目錄,通常所有自定義模塊放在該目錄下

# mkdir /srv/salt/_modules

2.編寫模塊

# vim test.py

# -*- coding: utf-8 -*-

'''

support for yum of RedHat family!

'''


def __virtual__():

   '''

   Only RedHat family os can use it.

   '''

   if __grains__.get('os_family', 'unkown') == 'RedHat':

       return 'yum'

   else:

       return False


def install(rpm):

   cmd = 'yum -y install {0}'.format(rpm)

   ret = __salt__['cmd.run'](cmd)

   return ret


說明: __virtual__函數通常用來匹配是否滿足該模塊的環境,如果滿足return出來的字符串作爲該模塊的名字而不是文件名,如果return的是False代表的此模塊無效,不能使用。在自定義模塊中可以中__grains__是一個包含了minion 所有grains的字典,__pillar__是包含了所有Pillar的grains字典,__salt__是所有可執行函數對象的字典,通常最常使用的就是這三個變量了。再往下面是定義了函數install,在salt中一般不用'%s' % var這種格式化形式,而是使用字符串的format方法,具體使用見百度。下面就是通過__salt__執行了cmd.run這個函數來運行yum命令,很簡單吧,最後把結果返回回去。

3.測試

# salt '*' yum.install ftp  ##查看返回值


二十二。自定義grains

自定義的grains也是由Python寫成的,通常放在/srv/salt/_grains下,grains需要返回一個字典,__salt__,__grains__,__pillar__也是可以在grains中使用的。前面已經介紹過寫簡單自定義grains了,複雜就就參照https://github.com/saltstack/salt/blob/develop/salt/grains/core.py官方這個吧


二十三。自定義returner

前面已經看過官方的mysql的returner了,今天來說說自定義returner需要注意的,來個例子吧。

/srv/salt/_returners/file.py內容


def __virtual__():

   return 'file'

def returner(ret):

   '''

   Return information to /tmp/returns.txt.

   '''

   # open a file

   result_file = '/tmp/returns.txt'

   f = open(result_file, 'a+')

   f.write(str(ret))

   f.close()

# salt '*' saltutil.sync_all         ##同步模塊

# salt '*' test.ping --return file   ##測試

# cat /tmp/returns.txt               ##在minion上查看

 {'jid': '20131227153001246117', 'return': True, 'retcode': 0, 'success': True, 'fun': 'test.ping', 'id': 'test1'}


說明:

通過這個簡單的例子我們瞭解返回的值是個字典,字典包括的項就是上面我們看到的,以後寫其它returner時,也就是把這個字典的值寫到不同的地方而已。這個returner的意思就是把返回的值寫到各個minion的/tmp/returns.txt中。



二十四。file state backup

來例子看看吧。

/srv/salt/test.sls文件內容


/tmp/test.txt:

 file.managed:

   - source: salt://test.txt

   - backup: minion


其中多了一個參數backup,後面跟的值minion,意思是說這個文件在minion中備份一份,文件名帶着時間戳,備份位置在/var/cache/salt/minion/file_backup


執行並測試:

# salt '*' state.sls test    ##注,多修改幾次test.txt,多運行幾次該state

# salt '*' file.list_backups /tmp/test.txt ##這是會返回備份序號,時間,位置,大小

 test1:

   ----------

...省略

   3:

       ----------

       Backup Time:

           Fri Dec 27 2013 16:44:05.840061

       Location:

           /var/cache/salt/minion/file_backup/tmp/test.txt_Fri_Dec_27_16:44:05_840061_2013

       Size:

           3300

   4:

       ----------

       Backup Time:

           Fri Dec 27 2013 16:32:47.785399

       Location:

           /var/cache/salt/minion/file_backup/tmp/test.txt_Fri_Dec_27_16:32:47_785399_2013

       Size:

           2


回退

當文件改錯後,我們可以用備份文件回退

# salt '*' file.restore_backup /tmp/test.txt 2   ##回退的文件,與想要回退的序列號

刪除

刪除不需要的備份文件

# salt '*' file.delete_backup /tmp/test.txt 3



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章