Table of Contents
1. SaltStack基礎知識和架構解析
1.1 SaltStack簡介
SaltStack是一種基於Python的一套C/S架構。其功能特別強大,集Ansible、Puppet功能於一身的管理工具,使用消息隊列ZeroMQ使得SaltStack能夠支持在數萬臺服務器上進行各種操作,而且使用RAS key方式確認身份,傳輸採用AES加密,且安全性能更高。
SaltStack不僅僅是一款配置管理工具,還是一款做雲計算和數據中心架構編排利器。目前,Salt-Cloud項目已經合併到SaltStack主項目中,SaltStack已經支持Docker相關模塊。
- Salt
一個配置管理系統,能夠維護定義狀態的遠程節點【可以是單個節點,也可以是任意規則挑選出來的節點】上執行命令和查詢數據
- Salt核心功能
- 使命令發送到遠程系統是並行的而不是串行的
- 使用安全加密的協議
- 使用最小最快的網絡載荷
- 提供簡單的編程接口
- Salt使用Python客戶端接口
爲允許進行簡便擴展,Salt的執行程序可以通過純Python模塊編寫。
數據從Salt執行過程中收集到可以發送回master服務端,或者發送到任何任意程序。
Salt可以從一個簡單的Python API調用,或者從命令行被調用,因此Salt可以用來執行一次性命令
1.2 SaltStack通訊機制
SaltStack採用C/S模式,minion與master之間通過ZeroMQ消息隊列【輕量級】通信,默認監聽端口是4505端口
Salt Master運行的第二個網絡服務就是ZeroMQ REP【請求響應】系統,默認監聽4506端口
master端口:4505
minion端口:4506
SaltStack的master端監聽4505和4506端口。其中4505爲Salt的消息發佈系統,4506爲Salt客戶端與服務端通信的端口;
Salt客戶端程序不監聽端口,客戶端啓動後,會主動連接master端註冊,然後一直保持TCP連接;
master通過該TCP連接對客戶端進行控制,若斷開,master也便無法控制客戶端,但是當客戶端檢測到斷開後會定期連接master端
1.3 ZeroMQ
ZeroMQ是一種基於消息隊列的多線程網絡庫,其對套接字類型、連接處理、幀、甚至路由的底層細節進行抽象,提供跨越多種傳輸協議的套接字。
ZeroMQ是網絡通信中新的一層,介於應用層和傳輸層之間,其是一個可伸縮層,可並行運行,分散在分佈式系統間。
1.4 傳統運維與自動化運維區別
1.4.1 傳統運維
- 傳統運維效率低下且繁瑣,大多工作人工完成,很容易出錯
- 傳統運維工作繁瑣,很容易出錯
- 傳統運維每日重複做相同的事情
- 傳統運維沒有標準化的流程
- 傳統運維的腳本繁多,不方便管理
1.4.2 自動化運維
Puppet:基於rubby開放,C/S架構,支持多平臺,可管理配置文件、用戶、cron任務、軟件包、系統服務等。分爲社區版和企業版,其中企業版支持圖形化配置;【官網:https://puppet.com】
SaltStack:基於Python開發,C/S架構,支持多平臺,比Puppet清量,在遠程執行命令時非常快捷,配置和使用比puppet容易,能實現puppet幾乎所有的功能;【官網:https://saltstack.com】
Ansible:更加簡潔的自動化運維工具,不需要在客戶端上安裝客戶端軟件,基於Python開發的。可以實現批量操作系統配置、批量程序的部署、批量執行命令。【Ansible中文文檔:http://www.ansible.com.cn】
1.5 SaltStack組件
SaltStack Master
中央管理系統(服務端):用來發送命令和配置到SaltStack Minion上運行
SaltStack Minion
接受管理系統(客戶端):用來接收來自SaltStack Master命令和配置
1.6 Salt具體步驟
- SaltStack的master與minion之間通過ZeroMQ來進行消息傳遞,使用了ZeroMQ的發佈-訂閱模式,連接方式包括:TCP、IPC。
- Salt命令其中以ls爲例。將cmd.run ls命令從salt.client.LocalClient.cmd_cli發佈到master,獲取一個jobid,根據jobid獲取命令執行結果。
- master接收到命令後,將要執行的命令發送給客戶端minion。
- minion從消息總線上接收到要處理的命令,交給minion._handle_aes處理。
- minion._handle_aes發起一個本地線程調用cmdmod執行ls命令。線程執行完ls後,調用minion._return_pub方法,將執行結果通過消息總線返回給master。
- master接收到客戶端返回的結果,調用master._handle_aes方法,將結果寫的文件中。
- salt.client.LocalClient.cmd_cli通過輪詢獲取Job執行結果,將結果輸出到終端。
1.7 SaltStack工具的軟件依賴
Python | 版本大於2.6或小於3.0 |
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包裝庫 |
2. 環境安裝及部署
2.1 實驗環境
主機信息 | 主機功能 |
server1(192.168.1.21) | master節點 |
server2(192.168.1.22) | minion節點1 |
server3(192.168.1.23) | minion節點2 |
關閉所有主機的firewalld、selinux
2.2 SaltStack的安裝與部署
官方網站:https://www.saltstack.com/
- 配置YUM倉庫【可以使用官網鏡像,但較慢,這裏我使用阿里雲鏡像倉庫】
配置官網鏡像倉庫:yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm
配置阿里雲鏡像倉庫:yum install https://mirrors.aliyun.com/saltstack/yum/redhat/salt-repo-latest-2.el7.noarch.rpm
- 在物理機上將安裝包下載好,通過httpd共享
下載地址:https://mirrors.aliyun.com/saltstack/yum/redhat/7.6/x86_64/2019.2/
- 在server1上編寫yum源配置文件
- server2和server3也需要yum源文件,複製一份到這兩臺主機
- 在server1上安裝master節點
- 在server2和server3上安裝minio節點
- 查看master節點配置文件【SaltStack使用root用戶通信】,開啓服務(主節點)
- 查看端口
4505端口用來鏈接slave,發佈訂閱
4506端口用來請求響應,模式爲:zmq(消息隊列)
- 修改minion節點配置文件(從節點),開啓服務
# 修改配置文件(注意書寫規範:每個冒號後面都要跟一個空格)
# 指定master爲server1
master: 192.168.1.21 # 這裏是指向salt-master服務器,可以是IP、域名或主機名
- 添加連接密鑰,在master添加minion
salt-key -L #查看當前證書的簽證情況(第一次客戶端的證書在未驗證Unaccepted Keys:的下面)
salt-key -A # -A(允許所有) -a(允許指定的) 通過此證書的驗證
salt-key -L #再次查看(發現出現在了Accepted Keys:下面表示已經通過了驗證,可以建立通信了)
- master 祕鑰對默認存儲在/etc/salt/pki/master/master.pub /etc/salt/pki/master/master.pem
- master 端認證的公鑰存儲在:/etc/salt/pki/master/minions/
- minion 祕鑰對默認存儲在/etc/salt/pki/minion/minion.pub /etc/salt/pki/minion/minion.pem
- minion 存放的master公鑰/etc/salt/pki/minion/minion_master.pub
- minion_id 默認存儲在/etc/salt/minion_id
若想修改minion名稱,需刪除原來的minion_id,重啓重新生成一個minion_id
- 測試
master端測試與minion端的連接,測試服務器端是否可以正常控制客戶端
salt '*' test.ping
- 安裝python-setproctitle,查看端口詳情,並查看每個進程的功能
3. yaml語法
3.1 yaml簡介
大家對於yaml語法應該不陌生,在ansible的playbook文件時使用的便是yaml語法。由於SaltStack也是用python編寫的,因此也要使用yaml語法。
默認的SLS文件的renderer是YAML renderer。YAML是一個由很多強大特性的標記性語言。Salt使用了一個YAML的小型子集,用來映射常用的數據結構,像列表和字典。YAML renderer的工作就是將YAML數據格式的結構編譯成爲Python數據結構給Salt使用。
掌握三個規則即可使用YAML語法書寫SLS文件
3.2 三個規則
- 規則一:縮進
YAML使用一個固定的縮進風格表示數據結構的層結構關係。Salt需要每個縮進級別由兩個空格組成,若要使用Tab,先修改.vimrc來設置Tab的縮進格數。
- 規則二:冒號
Python的字典當然理所當然是簡單的鍵值對。其他語言的用戶應該知道這個數據類型叫哈希表或者關聯數組。
字典的keys在YAML中的表現形式是一個以冒號結尾的字符串。Values的表現形式冒號下面的每一行,用一個空格隔開:
my_key: my_value
在Python中,上面的將映射爲:
{'my_key': 'my_value'}
另一種選擇,一個value可以通過縮進與key聯接。
my_key:my_value
註解:
上面的語法是有效的YAML,但是在SLS文件罕見,因爲通常情況下,一個key的value不是單一的,而是一個 列表 的values。
在Python中,上面的將映射爲:{'my_key': 'my_value'}
字典可以被嵌套:
first_level_dict_key:second_level_dict_key: value_in_second_level_dict
在Python中:
{
'first_level_dict_key': {
'second_level_dict_key': 'value_in_second_level_dict'
}
}
- 規則三:短橫槓
表示列表項:一個短橫槓加一個空格,多項則使用同樣縮進級別來作爲同一列表的一部分
- list_value_one
- list_value_two
做鍵值對的value
my_dictionary:
- list_value_one
- list_value_two
在Python中,上面的映射關係可以書寫爲:
{'my_dictionary': ['list_value_one', 'list_value_two']}
4. SaltStack遠程執行
4.1 Salt命令基礎知識
man salt 或者 salt -h # 查看salt命令使用方法
Salt命令主要由三個主要部分構成:salt '<target>' <function> [arguments]
target:指定哪些minion,默認的規則是使用glob匹配minion id # salt '*' test.ping
Targets也可以使用正則表達式 # salt -E 'server[1-3]' test.ping
Targets也可以指定列表 # salt -L 'server2,server3' test.ping
funcation:module提供的功能,Salt內置了大量有效的functions
arguments:通過空格來界定參數
- 查看模塊文檔
salt 'server2' sys.doc pkg #查看模塊文檔
- salt內置的執行模塊列表
http://docs.saltstack.cn/ref/modules/all/index.html
4.2 編寫遠程執行模塊
- 編寫master配置文件
vim /etc/salt/master
- 重啓master服務
systemctl restart salt-master.service
- 創建模塊目錄
mkdir -p /srv/salt/_modules
- 編寫模塊文件
vim /srv/salt/_modules/mydisk.py
- 同步模塊
salt server2 saltutil.sync_modules
- 運行模塊
salt server2 mydisk.df
- 配置管理
創建SLS文件
vim /srv/salt/apache.sls
指定主機執行
salt server2 state.sls apache
準備Top文件
vim /srv/salt/top.sls
批量執行
salt '*' state.highstate
因爲server2之前已經安裝過,因此直接說明已經安裝,server3成功安裝httpd
Salt 狀態系統的核心是SLS,或者叫SaLt State 文件。
SLS表示系統將會是什麼樣的一種狀態,而且是以一種很簡單的格式來包含這些數據,常被叫做配置管理。
sls文件命名:
- sls文件以”.sls”後綴結尾,但在調用時是不需要寫後綴的。
- 使用子目錄來做組織是個很好的選擇。
- init.sls 在一個子目錄裏面表示引導文件,也就表示子目錄本身, 所以``apache/init.sls`` 就是表示``apache``. 如果同時存在apache.sls 和 apache/init.sls,則 apache/init.sls 被忽略,apache.sls將被用來表示apache.
5. grains與pillar
5.1 grains
5.1.1 grains簡介
Grains是SaltStack的一個組件,它存放在SaltStack的minion端
當salt-minion啓動時會把收集到的數據靜態存放在Grains當中,只有當minion重啓時纔會進行數據的更新。由於grains是靜態數據,因此不推薦經常修改~
應用場景:
- 信息查詢,可用作CMDB
- 在target中使用,匹配minion
- 在state系統中使用,配置管理模塊
5.1.2 信息查詢
用於查詢minion端的IP、FQDN等信息
- 默認可用的grains
salt '*' grains.ls
- 查詢每一項的值:
salt '*' grains.items #items表示查看所有
salt '*' grains.item ipv4 ##只查看ip
5.1.3 自定義grains項
在/etc/salt/minion中定義
server2
vim /etc/salt/minion
- 重啓salt-minion
systemctl restart salt-minion
- 查看
salt server2 grains.item roles
在/etc/salt/grains中定義
server3
vim /etc/salt/grains
- 同步數據
salt server3 saltutil.sync_grains
- 查詢自定義項
salt server3 grains.item deployment
5.1.4 編寫grains模塊
在salt-master端創建_grains目錄
mkdir /srv/salt/_grains
vim /srv/salt/_grains/my_grain.py
同步grains到minion端
salt '*' saltutil.sync_grains
server2中之前設置了roles值,server3沒有,同步之後,可以發現server2的值還是原配置文件內容,並沒有被新的內容覆蓋
5.1.5 grains匹配運用
在target中匹配minion
salt -G roles:memcache cmd.run hostname
salt -G roles:nginx cmd.run hostname
在top文件中匹配
vim /srv/salt/top.sls
可以看到server2沒有匹配的grains因此報錯,server3已經安裝了httpd
5.2 pillar
5.2.1 pillar簡介
- pillar和grains一樣也是一個數據系統,兩個區別是應用場景不同
- pillar是將信息動態的存放在master端,主要存放私密、敏感信息(如用戶名密碼等),而且可以指定某一個minion纔可以看到對應的信息
- pillar更加適合在配置管理中運用
5.2.2 聲明pillar
定義pillar基礎目錄
vim /etc/salt/master
mkdir /srv/pillar
重啓salt-master服務
systemctl restart salt-master.service
5.2.3 自定義pillar項
vim /srv/pillar/top.sls
mkdir /srv/pillar/packages
vim /srv/pillar/packages/init.sls
刷新pillar數據
salt '*' saltutil.refresh_pillar
查詢pillar數據
salt '*' pillar.items
5.2.4 pillar數據匹配
命令行中匹配
salt -I 'package:httpd' test.ping
salt -I 'package:mairadb' test.ping
系統中使用pillar數據
vim /srv/salt/apache.sls
salt server3 state.sls apache
6. Jinja模板
6.1 Jinja模板簡介
- Jinja是一種基於python的模板引擎,在SLS文件裏可以直接使用jinja模板來做一些操作。 通過jinja模板可以爲不同服務器定義各自的變量。
- 兩種分隔符: {% ... %} 和 {{ ... }},前者用於執行諸如 for 循環或賦值的語句,後者把表達式的結果打印到模板上。
6.2 Jinja模板使用方式
Jinja最基本的用法是使用控制結構包裝條件
vim /srv/salt/testjinjia.sls
salt '*' state.sls testjinjia
Jinja在普通文件的使用
- 複製一份http配置文件到salt目錄下
cp /etc/httpd/conf/httpd.conf /srv/salt/
- 修改模板文件(引用變量port)
vim /srv/salt/httpd.conf
vim /srv/salt/apache.sls
salt '*' state.sls apache
- 在server2和server3上查看結果
import方式,可在state文件之間共享
- 定義變量文件
vim /srv/salt/lib.sls
- 導入
vim /srv/salt/httpd.conf
salt '*' state.sls apache
可以看到最終生效的是導入的變量,它覆蓋了我們在sls中定義的變量
7. Job管理
7.1 Job簡介
- master在下發指令任務時,會附帶上產生的jid
- minion在接收到指令開始執行時,會在本地的/var/cache/salt/minion/proc目錄下產生該jid命名的文件,用於在執行過程中master查看當前任務的執行情況
- 指令執行完畢將結果傳送給master後,刪除該臨時文件
7.2 Job cache
Job緩存默認保存24小時
vim /etc/salt/master
master端Job緩存目錄:/var/cache/salt/master/jobs
7.3 Job持久化(存儲到數據庫)
可以從master存儲到數據庫也可以從minion存儲,這裏我們選擇從master端存儲
修改master端配置
vim /etc/salt/master
重啓salt-master服務
systemctl restart salt-master.service
安裝數據庫以及相關插件
yum install -y mariadb-server MySQL-python
MySQL-python插件必須安裝,否則salt無法與mysql通信
啓動數據庫
systemctl start mariadb.service
安全初始化
mysql_secure_installation
創建sql模板
vim /srv/salt/salt.sql
導入數據庫
mysql -p < salt.sql
數據庫授權
grant all on salt.* to salt@'192.168.1.%' identified by 'salt';
因爲master和數據庫在同一主機,所以授權本機就可以,如果從minion上傳數據庫,那也要進行相應的授權
查看數據庫
執行一次遠程任務
再次查看數據庫
7.4 Job管理
查看所有minion當前正在運行的jobs(在所有minions上運行saltutil.running)
salt-run jobs.active
列出當前master jobs cache中所有job
salt-run jobs.list_jobs
從master jobs cache中查詢指定jid的運行結果
salt-run jobs.lookup_jid <jid>
8. Salt-ssh和Salt-syndic
8.1 Salt-ssh
8.1.1 Salt-ssh簡介
- salt-ssh可以獨立運行的,不需要minion端。
- salt-ssh 用的是sshpass進行密碼交互的。
- 以串行模式工作,性能下降。
8.1.2 Salt-ssh安裝與配置
- 安裝salt-ssh
yum install -y salt-ssh
- 配置roster(相當於ansible的inventory清單)文件
vim /etc/salt/roster
- 測試
salt-ssh '*' test.ping -i
8.2 Salt-syndic
8.2.1 Salt-syndic簡介
- 學習過zabbix proxy就很容易理解了,syndic其實就是個代理,隔離master與minion
- Syndic必須要運行在master上,再連接到另一個topmaster上
- Topmaster 下發的狀態需要通過syndic來傳遞給下級master,minion傳遞給master的數據也是由syndic傳遞給topmaster。
- top master並不知道有多少個minion
- syndic與topmaster的file_roots和pillar_roots的目錄要保持一致
8.2.2 Salt-syndic配置
topmaster端(server4:192.168.1.24)
- 安裝salt-master
yum install -y salt-master.noarch
- 修改master配置文件,使其成爲頂級master
vim /etc/salt/master
- 開啓salt-master
systemctl start salt-master.service
下級master端(server4:192.168.1.24)
- 安裝salt-syndic
yum install -y salt-syndic
- 修改master配置文件
vim /etc/salt/master
- 重啓服務
systemctl restart salt-master
systemctl start salt-syndic
topmaster端查看
- 測試
可以看到實際執行操作的是server2和server3
9. salt-api
9.1 salt-api簡介
SaltStack 官方提供有REST API格式的 salt-api 項目,將使Salt與第三方系統集成變得尤爲簡單。
官方提供了三種api模塊:
rest_cherrpy
rest_tornado
rest_wsgi
官方鏈接:https://docs.saltstack.com/en/latest/ref/netapi/all/index.html#all-netapi-modules
9.2 salt-api配置
- 安裝salt-api
yum install -y salt-api.noarch python-cherrypy.noarch
- 生成證書
cd /etc/pki/tls/private
openssl genrsa 2048 > localhost.key
cd /etc/pki/tls/certs
make testcert //根據提示填寫相關信息
- 創建用戶認證文件
useradd -s /sbin/nologin saltapi
echo redhat | passwd --stdin saltapi
vim /etc/salt/master.d/auth.conf
- 激活rest_cherrypy模塊
vim /etc/salt/master.d/api.conf
- 打開include加載自配置文件
vim /etc/salt/master
- 重啓服務
systemctl restart salt-master
systemctl start salt-api
9.3 salt-api使用
- 獲取認證token
curl -sSk https://192.168.1.24:8000/login
-H 'Accept: application/x-yaml'
-d username=saltapi
-d password=redhat
-d eauth=pam
- 推送任務
curl -sSk https://192.168.1.24:8000
-H 'Accept: application/x-yaml'
-H 'X-Auth-Token: 4308a2affee7640d9762823a154d01d18272516c'
-d client=local
-d tgt='*'
-d fun=test.ping