寫在前面的話
上一節談及了 Saltstack 的安裝和初始化配置,本節将談談 Saltstack 中兩個重要的東西,Grains 和 Pillar。
資料系統 Grains 入門
Grains 是靜态資料,其資料來源于 Minion 啟動的時候收集的有關用戶端本地的相關資訊。
包括作業系統,核心,CPU,記憶體,硬碟,裝置型号等等。這就意味着我們可以使用 Saltstack 做資産管理。
這些靜态資料除非是 Minion 重新開機或者 Master 端主動同步更新,否則不會改變。
1. 檢視 grains 預設支援的 Key:
salt 'saltstack-node-01' grains.ls
結果如下:

我們可以看到超級多的 Key。我這裡隻截圖了一小部分。grains.ls 這其實就是 python 裡面引用 grains 子產品中的 ls 方法。
2. 檢視所有 Key 的值:
salt 'saltstack-node-01' grains.items
結果如圖:
傳回的結果其實就是 YAML 格式,後面會單獨的提到 YAML 文法特點。這裡我們隻需要知道其實就是 K/V 結構就行。
3. 檢視單獨某個 Key 的值:
salt 'saltstack-node-01' grains.item os
結果如圖:
這裡差別檢視所有,item 采用單數的形式,如果該 Key 不存在或者沒值,那麼就不會有下面綠色部分的顯示。
4. 我們就可以根據這裡的 KV 來就行選擇特定的機器,類似 K8S 中的标簽選擇器(Label Selector):
salt -G 'os:CentOS' cmd.run 'uptime'
注意,如果我們用 KV 選擇需要使用 -G 參數。且這裡的冒号後面沒空格。
5. 當然,預設的 grains 可能無法滿足我們的需求,我們可以自定義,一共有兩種方法:
方法 1:在 /etc/salt/minion 配置檔案的 129 行 有關于 grains 的配置(不同版本可能不一樣)
可以添加一下配置進行測試:
grains:
roles: app-server
注意 roles 前面空格 2 個,roles 後面 : 後面空格 1 個,這是 YAML 文法要求。
然後我們重新開機 minion 測試一下:
systemctl restart salt-minion
在 Master 檢視:
salt '*' grains.item roles
可以發現剛剛添加的 node3 節點已經能夠看到我們新添加的 KV 配置了。
方法 2:通過方法 1 我們發現,如果都寫到 minion 配置檔案,不便于我們管理,所有我們可以抽離出來:
我們可以建立 /etc/salt/grains 檔案,該檔案能夠自動被 salt 識别,直接在内部寫 KV:
server_env: product
server_name: mall-server
注意冒号後面有個空格。我們也可以不重新開機 minion,直接在 Master 端同步,然後再度檢視:
# 不重新開機直接同步
salt '*' saltutil.sync_grains
# 檢視多個
salt '*' grains.item server_env server_name
6. 或者某個 Key 的值我們還可以使用如下方法:
salt '*' grains.get os
對比 grains.item 檢視結果:
我們發現使用 item 相對于使用 get 多顯示了 Key。
7. 自己用 Python 開發一個 grains: 方法就是寫個腳本,傳回一個字典即可。
首先我們需要修改 master 的配置檔案:/etc/salt/master 在目前版本的 658 行有關于 file_roots 的配置,我們把配置放開。
file_roots:
base:
- /srv/salt
該目錄同時也用于我們之後寫 YAML 檔案使用。當然這個目錄不存在,還需要我們在 Master 節點手動建立。
# 重新開機 Master
systemctl restart salt-master
# 建立目錄
mkdir /srv/salt
我們存放 Python 腳本的目錄為:_grains
cd /srv/salt/ && mkdir _grains
我們在下面建立一個擷取時間的 Python 腳本:get_time.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import time
def get_time():
grains = {}
grains['year'] = time.localtime().tm_year
grains['month'] = time.localtime().tm_mon
grains['day'] = time.localtime().tm_mday
return grains
然後同步到所有 Minion 節點:
salt '*' saltutil.sync_grains
我們可以檢視同步之後的腳本在 Minion 節點放到了什麼位置:
tree /var/cache/salt/
我們需要知道的是 /var/cache/salt 目錄相當重要,從 Master 端同步的都會放到該目錄下,其中紅色部分就是能夠執行的代碼。
可以直接檢視剛剛我們定義的那些 Key:
salt '*' grains.item year
如果這過程中出現問題,我們都可以檢視日志:/var/log/salt/minion
當然,在我們定義 grains 的時候,可能會和系統的名稱出現一樣的情況,這就牽扯到一個優先級:
系統自帶 > grains 檔案中 > minion 中寫的 > 自己寫的
資料系統 Pillar 入門
Pillar 相比于 Grains,首先 Pillar 是動态的資料。其次 Pillar 定義在 Master 上面,隻有特定的節點能看到,是以安全。
我們可以檢視目前系統中的 Pillar 資料:
salt '*' pillar.items
可以看到目前是沒資料的,但是其實系統是有一部分資料的,隻是被隐藏了而已,如果你确實想看,可以通過修改 Master 配置實作檢視,配置在 /etc/salt/master 的 878 行(我目前的版本),修改配置為如下配置,再度重新開機 Master 即可:
pillar_opts: True
其最終檢視的結果其實際是一個叫做 master 的字典,但是并不推薦開啟,因為不便于管理 pillar 配置。
我們從前面知道了 Grains 是可以直接在 minion 配置檔案中定義的,那麼 Pillar 需要這麼定義呢?此時就可以看出 Grains 和 Pillar 的明顯不同,Grains 配置在 Minion 端,Pillar 配置在 Master 端,且 Pillar 使用我們後面會經常用到的 sls 檔案進行管理。至于 sls 的具體使用方法,後面會單獨詳講。
1. 我們需要通過修改 master 配置檔案,放開 Pillar 配置,在 /etc/salt/master 我目前版本的 828 行:
pillar_roots:
base:
- /srv/pillar
重新開機 Master 建立目錄:
# 重新開機
systemctl restart salt-master
# 建立目錄
/srv/pillar
# 檢視目錄結構
tree /srv/
2. 為了更好的進行管理,可以對 sls 檔案進行歸類,我們這裡在 pillar 下面建立一個 test 目錄,用于存放測試 sls 檔案:
cd /srv/pillar/ && mkdir test
# 建立配置
vim server_role.sls
内容如下:
{% if grains['fqdn'] == 'demo-node1' %}
salt_role: master
{% else %}
salt_role: minion
{% endif %}
在該配置中我們加入了 Grains 判斷。至于這個檔案的文法,如果你學過 Python 并且使用過 Django 你就會發現特别熟悉,沒錯,Jinja2 文法。後面也會詳講,這裡先簡單應用。該配置大緻意思就是根據主機名給不同的 Minion 設定不同的角色屬性。
3. 建立 top.sls,在 Saltstack 中 sls 配置有一個統一的入口,那就是 top.sls 檔案,我們這裡也是簡單的應用,後面講到配置的時候單獨詳講,先有這麼個概念和印象就行。
vim top.sls
base:
'*':
- test.server_role
簡單做個說明:* 指代所有主機,你也可以寫特定的主機或者通配符,因為我們建立了 test 目錄,所有我們得像 Python 調用子產品一樣,使用 test.server_role 來調用配置檔案。此時可以檢視下目錄結構:
4. 同步配置,可以像 grains 一樣不用重新開機直接同步:
salt '*' saltutil.refresh_pillar
結果如下:
再度檢視:
salt '*' pillar.item salt_role
結構如圖:
5. 使用選擇器執行想要的:
salt -I 'salt_role:master' cmd.run 'w'
檢視結果:
注意:這裡 Pillar 的規則需要使用 -I (大寫 i)參數,就行 Grains 需要使用 -G 參數一樣。同時可能會遇到這樣的情況,如下:
對于 Minion did not return. [No response] 這種問題,一般重新開機 minion 端就能解決。
小結
通過對比 Grains 和 Pillar,我們會發現其最大的特點有以下幾個:
1. Grains 主要配置在 Monion,而 Pillar 主要配置在 Master。
2. Grains 可以自己用 Python 寫方法,傳回一個字典就行。Pillar 則是用 Salt 最為主要的 sls 配置。
3. Grains 一般是靜态資料,雖然自定義的可以使用方法動态擷取,而 Pillar 則是可以利用 Jinja2 模闆進行邏輯判斷。
4. Grains 和 Pillar 都能很好的支援資料查詢,配置管理,Pillar 還能夠進行敏感資料管理。
5. 兩者都能很好的協助我們通過類似标簽選擇器(Label Selector)的方式對伺服器進行批量選擇。
注意:這裡所說的所謂保護敏感資料其實是因為我們在 Master 端做的定義,這樣即使黑客攻陷了某台 Minion 他也無法拿到敏感資料而已。