Linux——Salt Stack自動化部署

2020-08-14 19:09:36

Salt Slack

簡介

SaltStack、Ansible、Puppet比較

(1)SaltStack(一般用於大於1000台伺服器的公司環境)
saltStack由Python編寫,爲server-client模式的系統,自己本身支援多master。執行模式爲master端下發指令,用戶端接收指令執行。saltstack依賴於zeromq訊息佇列,採用yaml格式編寫組態檔,比較簡單。支援api及自定義python模組,能輕鬆實現功能擴充套件。

(2)Ansible (應用於1000台以下伺服器的環境)
   類似與saltstack,基於python開發,關注的重點是精簡和快速。不需要在節點安裝代理軟體,通過ssh執行所有功能,安裝執行簡單。其模組可以用任何語言開發,採用yaml格式編寫組態檔。沒有用戶端,較難擴充套件。

(3)Puppet(慢慢的被市場淘汰)
   puppet由Ruby編寫,爲server-client模式的系統。執行時由用戶端定時去獲取自己的組態檔進而應用更改。也可以通過master的push命令即可觸發變更。將命令,檔案,服務等抽象成資源,概念比較統一,時間悠久,文件較多。就可用操作,模組,用戶介面等等功能而言,是三者之中最全面的。安裝部署難度一般,設定清單相對於其他工具較複雜。

安裝

1.salt軟體包需要epel源的支援

[root@master ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@master ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@master ~]# yum clean all #清空快取
[root@master ~]# yum makecache #生成yum快取

2.安裝salt

[root@master ~]# yum -y install salt-master salt-minion
[root@master ~]# systemctl start salt-master.service 
[root@master ~]# systemctl start salt-minion.service 

salt-master:伺服器端

salt-minion:被管理端

4505 publish_port 提供遠端命令發送功能
4506 ret_port 提供認證,檔案服務,結果收集等功能

3.修改組態檔

master

[root@master ~]# grep -v ^# /etc/salt/master |grep -v ^$
interface: 0.0.0.0
#系結到原生的0.0.0.0地址
publish_port: 4505
#管理埠,命令發送
user: root
#執行salt進程的使用者
worker_threads: 5
#salt執行執行緒數,執行緒越多處理速度越快,不要超過cpu個數
ret_port: 4506
#執行結果返回埠
pidfile: /var/run/salt-master.pid
#pid檔案位置
auto_accept: False
#自動接收minion的key
log_file: /var/log/salt/master
#日誌檔案地址

PS:在master端/etc/salt/master設定

auto_accept: True #如果對Minion信任,可以設定master自動接受請求

minion

[root@master ~]# grep -v ^# /etc/salt/minion|grep -v ^$
master: 192.168.1.11
#master伺服器的ip
master_port: 4506
#master伺服器的埠
user: root
#使用者
id: node1
#主機名
acceptance_wait_time: 10
log_file: /var/log/salt/minion
#日誌檔案地址
[root@master ~]# systemctl restart salt-master.service 
[root@master ~]# systemctl restart salt-minion.service

4.檢視組態檔

master

[root@master ~]# rpm -ql 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
/usr/lib/systemd/system/salt-master.service
/usr/share/man/man1/salt-cp.1.gz
/usr/share/man/man1/salt-key.1.gz
/usr/share/man/man1/salt-master.1.gz
/usr/share/man/man1/salt-run.1.gz
/usr/share/man/man1/salt-unity.1.gz
/usr/share/man/man7/salt.7.gz

minion

[root@master ~]# rpm -ql salt-minion 
/etc/salt/minion 	#minion組態檔
/usr/bin/salt-call 	#拉取命令
/usr/bin/salt-minion	#minion服務命令
/usr/lib/systemd/system/salt-minion.service	#minion啓動指令碼
/usr/share/man/man1/salt-call.1.gz
/usr/share/man/man1/salt-minion.1.gz

5.master上接收minion祕鑰

​ 在minion啓動後連線master會請求master爲其簽發證書,等待證書籤發完成後,master可以信任minion,並且minion和master之間的通訊是加密的。

常用參數

參數 解釋
-L 檢視KEY狀態
-A 允許所有
-D 刪除所有
-a 認證指定的key
-d 刪除指定的key
-r 註銷掉指定key(該狀態爲未被認證)
[root@master ~]# salt-key -L
Accepted Keys:   #已經接受的key
Denied Keys:     #拒絕的key
Unaccepted Keys: #未加入的key
node1 
Rejected Keys:   #吊銷的key
  #此時slave已經出現在unaccepted keys中,說明minion已經和master聯繫,並且master已經獲取了minion的公鑰,等待下一步指令。
[root@master ~]# salt-key -f node1
Unaccepted Keys:
node1:  a1:e9:9e:d1:d6:fd:7c:5a:4e:31:37:c3:76:41:6e:44
  #在master上檢視minion的祕鑰
[root@slave ~]# salt-call --local key.finger
local:
    a1:e9:9e:d1:d6:fd:7c:5a:4e:31:37:c3:76:41:6e:44
    #在minion上獲取minion的祕鑰
[root@master ~]# salt-key -a node1
The following keys are going to be accepted:
Unaccepted Keys:
node1
Proceed? [n/Y] y
Key for minion node1 accepted.
	#在master上接收祕鑰
[root@master ~]# salt-key -L
Accepted Keys:
node1
Denied Keys:
Unaccepted Keys:
Rejected Keys:
	#檢視master有沒有獲取到minion的祕鑰日常

日常命令

1.test

[root@master ~]# salt '*' test.ping
node1:
    True
  • salt 是一個命表示目標主機, 在這裏代表所有目標主機

  • test.ping是salt遠端執行的一個模組下面 下麪的方法。這是條很簡單的探測minion主機存活命令,也是遠端執行命令,我們通過master發送訊息給"*"所有的minion,並且告訴他們執行salt內建的命令(也是python模組中的一個函數),返回true表示slave機器監控存活。

test的其他函數:

test.echo

[root@master ~]# salt '*' test.echo 'heel linux'
node1:
    heel linux

test.fib生成斐波那契數列

[root@master ~]# salt '*' test.fib 10
node1:
    |_
      - 0
      - 1
      - 1
      - 2
      - 3
      - 5
      - 8
    - 3.81469726562e-06

PS:菲波那切數列定義是第0項是0,第1項是1,數列從第3項開始,每一項等於前兩項之和。

2.命令組成結構

(1)完整的五部分命令

–summary參數顯示salt命令的概要

[root@master ~]# salt --summary '*' cmd.run 'hostname'
node1:
    master


-------------------------------------------
Summary
-------------------------------------------
# of Minions Targeted: 1
# of Minions Returned: 1
# of Minions Did Not Return: 0
-------------------------------------------

(2)列出所有salt的sys模組

PS:與系統互動的sys模組

[root@master ~]# salt 'node1' sys.list_modules
node1:
    - acl
    - aliases
    - alternatives
    - archive
    - artifactory
......

案例

環境

主機Ip 主機名
192.168.1.11 master(node1)
192.168.1.10 minion(node2)

PS:伺服器端安裝salt-master,被管理端安裝salt-minion,修改組態檔,關閉防火牆和SElinux

遠端執行模組

1.cmd是超級模組,所有shell命令都能執行

[root@master ~]# salt 'node2' cmd.run 'pwd'
node2:
    /root

2.遠端安裝nginx

[root@master ~]# salt 'node2' pkg.install "nginx"
#安裝nginx
[root@master ~]# salt 'node2' pkg.version "nginx"
node2:
#檢視nginx版本
[root@master ~]# salt 'node2' pkg.remove "nginx"
#解除安裝nginx

3.遠端管理服務模組

​ 管理服務是系統管理員的重要任務,通過salt管理minion服務會很簡單,使用service模組

PS:確保以安裝nginx

[root@master ~]# salt 'node2' service.start "nginx"
node2:
    True
    #開啓nginx
[root@master ~]# salt 'node2' service.status "nginx"
node2:
    True
    #檢視nginx狀態
[root@master ~]# salt 'node2' service.stop "nginx"
node2:
    True
    #關閉nginx

4.小實驗

#開啓nginx
[root@master ~]# salt 'node2' service.start "nginx"
node2:
    True
#用cmd檢視nginx的狀態
[root@master ~]# salt 'node2' cmd.run 'systemctl status nginx'
node2:
    * nginx.service - The nginx HTTP and reverse proxy server
       Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
       Active: active (running) since Wed 2020-08-12 20:29:37 CST; 46s ago
      Process: 17355 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
      Process: 17352 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
      Process: 17350 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
     Main PID: 17357 (nginx)
       CGroup: /system.slice/nginx.service
               |-17357 nginx: master process /usr/sbin/ngin
               |-17358 nginx: worker proces
               `-17359 nginx: worker proces
    
    Aug 12 20:29:37 minion systemd[1]: Starting The nginx HTTP and reverse proxy server...
    Aug 12 20:29:37 minion nginx[17352]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    Aug 12 20:29:37 minion nginx[17352]: nginx: configuration file /etc/nginx/nginx.conf test is successful
    Aug 12 20:29:37 minion systemd[1]: Started The nginx HTTP and reverse proxy server.

out命令的用法

PS:out與標準的Linux、salt的命令一樣用法

  • –out控制salt命令結果輸出的格式

JSON

[root@master ~]# salt --out=json '*' cmd.run_all 'hostname'
{
    "node2": {
        "pid": 17373, 
        "retcode": 0, 
        "stderr": "", 
        "stdout": "minion"
    }
}
{
    "node1": {
        "pid": 19729, 
        "retcode": 0, 
        "stderr": "", 
        "stdout": "master"
    }
}

YAML

[root@master ~]# salt --out=yaml '*' cmd.run_all 'hostname'
node2:
  pid: 17379
  retcode: 0
  stderr: ''
  stdout: minion
node1:
  pid: 29762
  retcode: 0
  stderr: ''
  stdout: master

編寫States

States簡稱SLS檔案。這個檔案遵循YAML語法。

json xml yaml 數據序列化格式,yaml容易被解析,應用於組態檔。

salt的組態檔是yaml組態檔,不能用tab,saltstack,k8s,ansible都用的yaml格式組態檔

語法規則

  • 大小寫敏感
  • 使用縮排表示層級關係
  • 縮排時禁止tab鍵,只能空格
  • 縮排的空格數不重要,相同層級的元素左側對其即可
  • #號表示註釋行

yaml支援的數據結構

  • 物件: 鍵值對,也稱作對映 mapping 雜湊hashes 字典dict 冒號表示 key: value key冒號後必須有空格
  • 陣列: 一組按次序排列的值,又稱爲序列sequence 列表list 短橫線 - list1
  • 純量: 單個不可再分的值

物件:鍵值對

yaml
    first_key:
      second_key:second_value

python
    {
        'first_key':{
            'second_key':'second_value',
        }
    }

​ YAML是YAML Ain’t Markup Language的首字母縮寫,YAML的語法簡單,結構體通過空格展示專案使用 ‘-’ 代表,鍵值對通過 ‘:’ 分割。
​ YAML語法遵循固定的縮排風格,表示數據層級結構關係,saltstack需要每個縮排級別由2個空格組成,禁止用tabs!!!
​ Python中的字典是簡單的鍵值對,go語言中稱作雜湊表map字典的key通過冒號分割。

​ key在YAML中表現形式是一個冒號結果的字串 my_key: my_value轉化到python語法中,上述命令爲{‘my_key’:‘my_value’}

​ value還可以通過縮排和key關聯,四個空格!!my_key: my_value 轉化爲python語法同樣的{‘my_key’:‘my_value’}

​ YAML語法中字典是可以巢狀的one_dict_key: two_dict_key:value_dict轉化爲python語法

{
  'one_dict_key':{
    'two_dict_key':'value_dict'
  }
}

短橫槓

​ YAML語法表示列表,使用一個橫槓加一個空格多個項使用同樣的縮排級別作爲同一個列表的部分,列表可以作爲一個鍵值對的value,例如一次性要安裝多個軟體

my_dict:
  - l1
  - l2
  - l3
轉化爲python程式碼理解就是
{
  'my_dict':['l1','l2',;l3]
}

state模組

​ 之前執行的遠端命令,都是一個過程式的,類似一段shell或者python指令碼執行,執行一次觸發一次相同的功能。那麼大量的minion上執行遠端命令就必須使用salt提供的「狀態管理」了,狀態是對minion的一種描述和定義,運維不需要關心部署是如何完成的,只需要描述minion需要達到什麼狀態。

state模組部署nginx

(1)master端

[root@master ~]# vim /etc/salt/master 
file_roots:
  base:
    - /srv/salt/base
 dev:
   - /srv/salt/dev
 test:
   - /srv/salt/test
 prod:
   - /srv/salt/prod
[root@master ~]# systemctl restart salt-master.service 

(2)master、minion都執行

[root@master ~]# mkdir -p /srv/salt/{base,dev,test,prod}
[root@minion ~]#  mkdir -p /srv/salt/{base,dev,test,prod}
#master
[root@minion ~]# vim /srv/salt/base/nginx.sls
nginx-install:
  pkg.installed:
    - name: nginx

nginx-service:
  service.running:
    - name: nginx
    - enable: True
#minion
[root@master ~]# cat /srv/salt/base/nginx.sls
nginx-install:
  pkg.installed:
    - name: nginx

nginx-service:
  service.running:
    - name: nginx
    - enable: True

​ sls組態檔都遵循YAML語言描述,第一條命令使用了pkg.install安裝命令,相對於執行了yum install,而此時state模組會判斷nginx是否安裝了,如果沒有安裝就進行安裝,安裝了就什麼都不做。狀態描述都會遵循這個原則,只有檢測到真實狀態和所需狀態不一就會執行此功能,這種性質叫做冪等性。此時用state模組部署nginx軟體,通過我們編寫的nginx.sls描述性組態檔,命令列呼叫state模組的sls函數。

(3)啓動命令

[root@master ~]# salt 'node2' state.sls nginx
node2:
----------
          ID: nginx-install
    Function: pkg.installed
        Name: nginx
      Result: True
     Comment: Package nginx is already installed.
     Started: 20:53:28.178139
    Duration: 545.41 ms
     Changes:   
----------
          ID: nginx-service
    Function: service.running
        Name: nginx
      Result: True
     Comment: Service nginx has been enabled, and is in the desired state
     Started: 20:53:28.724378
    Duration: 382.476 ms
     Changes:   
              ----------
              nginx:
                  True

Summary
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2

PS:如果直接安裝過nginx,可以用戶端關閉nginx,刪除nginx,重新執行命令,一樣可以安裝啓動nginx

(4)檢視nginx狀態

[root@master ~]# salt 'node2' cmd.run 'systemctl status nginx'
node2:
    * nginx.service - The nginx HTTP and reverse proxy server
       Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
       Active: active (running) since Wed 2020-08-12 20:29:37 CST; 25min ago
     Main PID: 17357 (nginx)
       CGroup: /system.slice/nginx.service
               |-17357 nginx: master process /usr/sbin/ngin
               |-17358 nginx: worker proces
               `-17359 nginx: worker proces
    
    Aug 12 20:29:37 minion systemd[1]: Starting The nginx HTTP and reverse proxy server...
    Aug 12 20:29:37 minion nginx[17352]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    Aug 12 20:29:37 minion nginx[17352]: nginx: configuration file /etc/nginx/nginx.conf test is successful
    Aug 12 20:29:37 minion systemd[1]: Started The nginx HTTP and reverse proxy server.

採集資訊

​ Grains 是saltstack元件中非常重要之一,在設定部署時候經常使用,Grains記錄minion的靜態資訊,比如常用屬性,CPU、記憶體、磁碟、網路資訊等。
Minions的Grains資訊是Minion啓動時採集彙報給Master的,Grains是以 key value形式儲存的數據庫,可以看做Host的元數據(metadata),Grains儲存着收集到的用戶端的詳細資訊,如果slave機器數據變化,grains就過期了,在生產環境中需要自定義Grains,可以通過:
​ Minion組態檔
​ Grains相關模組定義
​ Python指令碼定義

使用系統Grains數據

檢視grains的命令用法

[root@master ~]# salt 'node2'  sys.doc grains

列出主機所有Grains數據

[root@master ~]# salt 'node2' grains.items

列出所有grains方法

[root@master ~]# salt 'node2'  grains.ls

.檢索某些數據

[root@master ~]# salt 'node2'  grains.item os id host
node2:
    ----------
    host:
        minion
    id:
        node2
    os:
        CentOS
[root@master ~]# salt 'node2'  grains.item key1 key2 key3   # 利用Grains靜態資訊定位主機
node2:
    ----------
    key1:
    key2:
    key3:

定位Cenots的機器

[root@master ~]# salt -G 'os:Centos' test.ping
node1:
    True
node2:
    True

定位元運算系統系統是7系列的機器

[root@master ~]# salt -G 'osrelease:7*' test.ping
node1:
    True
node2:
    True

找出ip地址

[root@master ~]# salt '*' grains.item fqdn_ip4
node1:
    ----------
    fqdn_ip4:
        - 192.168.1.11
node2:
    ----------
    fqdn_ip4:
        - 192.168.1.10

自定義設定Grains數據

設定數據

[root@master ~]# salt 'node1' grains.setval cpu_num 8
node1:
    ----------
    cpu_num:
        8

查詢數據

[root@master ~]# salt 'node1' grains.item cpu_num
node1:
    ----------
    cpu_num:
        8

PS:在master端設定Grains靜態數據,原理會將此數據新增到minion伺服器的組態檔的/etc/salt/grains。

minion端檢視

[root@minion ~]# cat /etc/salt/grains 
cpu_num: 8

JSON語法

對於複雜的數據結構,可以新增靈活的JSON語法

[root@master ~]# salt 'node1' grains.setval cpu_info '["Intel","Xeon","10"]'
node1:
    ----------
    cpu_info:
        - Intel
        - Xeon
        - 10
[root@master ~]# salt 'node1' grains.item cpu_info
node1:
    ----------
    cpu_info:
        - Intel
        - Xeon
        - 10

此時可以檢查minion伺服器上的grains檔案

[root@minion ~]# cat /etc/salt/grains 
cpu_info:
- Intel
- Xeon
- '10'
cpu_num: 8

PS:Grains數據寫入組態檔後,重新啓動salt-minion服務,數據也不會丟失

清空值

​ 想要刪除可以通過grains.delval命令刪除,或者去minion的組態檔刪除設定一樣完成操作(或者刪除檔案)

方法一:

[root@master ~]# salt 'node1' grains.delval cpu_info
node1:
    None
[root@master ~]# salt 'node1' grains.delval cpu_num
node1:
    None
[root@master ~]# cat /etc/salt/grains 
cpu_info: null
cpu_num: null

方法二:

[root@minion ~]# cat /etc/salt/grains 
cpu_info:
- Intel
- Xeon
- '10'
cpu_num: 8
[root@minion ~]# rm -rf /etc/salt/grains
[root@minion ~]# systemctl restart salt-minion.service 
[root@minion ~]# cat /etc/salt/grains 
cat: /etc/salt/grains: No such file or directory

Pillar

​ Pillar也是saltstack元件中非常重要的元件之一,稱作數據管理中心,經常配合states在大規模的設定管理中使用。

​ Pillar是動態的,儲存在master端,提供和給minion端。

​ Pillar在SaltStack中主要的作用是儲存和定義設定管理中需要的一些數據,比如軟體版本號,使用者賬號密碼等,保證敏感數據不被其他minion看到。儲存格式與Grains類似,都是YAML格式。

在master組態檔中有一段Pillar settings選項專門定義Pillar的參數

[root@master ~]# vim /etc/salt/master 
#此設定代表pillar的工作根目錄,在/srv/pillar下,然後可以新建sls檔案
#pillar_roots:
#  base:
#    - /srv/pillar
刪除#號
[root@master ~]# mkdir -p /srv/pillar   //建立工作目錄

指定環境,標記參照packages.sls和services.sls

[root@master ~]# vim /srv/pillar/top.sls
base:
  '*':
      - packages
      - services
[root@master ~]# vim /srv/pillar/packages.sls
nginx:
    packages-name: nginx
    version: 1.12.2

[root@master ~]# vim /srv/pillar/services.sls
nginx:
    port: 80
    user: root

檢查設定的pillar值

[root@master ~]# salt 'node2'  pillar.item nginx
node2:
    ----------
    nginx:
        ----------
        packages-name:
            nginx
        port:
            80
        user:
            root
        version:
            1.12.2

pillar與Grains對比

型別 數據採集方式 應用場景 定義位置
Grains 靜態 minion啓動時收集 數據查詢 目標選擇 設定管理 minion
Pillar 動態 master進行自定義 目標選擇 設定管理 敏感數據 master