天天看點

自動化運維工具之Saltstack

一、簡介

what  is Saltstack?

Saltstack是一個具備puppet與func功能為一身的集中化管理平台,saltstack基于python實作,功能十分強大,适合大規模批量管理伺服器,并且它比 Puppet 更容易配置。saltstack具有三種基本功能包括遠端指令執行,配置管理(服務,檔案,cron,使用者,組),雲管理。同時,saltstack具有三種運作方式Local、master/minon 、salt ssh。其中master/minion是其最傳統的運作方式采用c/s模式,需要在管理端安裝Master,被管理節點上安裝Minion;而Saltstack salt ssh 運作方式,可以實作無需安Agent,通過SSH進行管理。

Saltstack部署架構

master->minion:master和所有minion連接配接,minion接收來自master的指令,完成指令執行或配置。如圖:

<a href="https://s1.51cto.com/oss/201711/22/28bd649378ba813ad2de8b202881e745.png-wh_500x0-wm_3-wmp_4-s_2322396488.png" target="_blank"></a>

master-&gt;syndic-&gt;minion:master通過syndic對minion進行管理,該架構可以進行多級擴充。如圖:

<a href="https://s4.51cto.com/oss/201711/22/ccb8204d6409a4e5f3b696dc41e84c77.png-wh_500x0-wm_3-wmp_4-s_912416081.png" target="_blank"></a>

無master的minion:minion不受任何master控制,通過本地運作即可完成相關功能。

<a href="https://s2.51cto.com/oss/201711/22/8b3e2f87fb4d6536b3c292cd85f375cf.png-wh_500x0-wm_3-wmp_4-s_2666300786.png" target="_blank"></a>

Saltstack的兩種主要設計理念是遠端執行和配置管理。在遠端執行系統中,salt用python通過函數調用來完成任務。salt中的配置管理系統可以稱作state,也是基于遠端執行系統之上,通過master的定規可以讓對應的minion達到想要的系統狀态。

salt遠端執行底層原理:

Salt的底層通信是通過ZeroMQ完成的,采用了ZeroMQ的訂閱釋出模式(Pub和Sub)如下圖所示:

    簡單來講,Pub/Sub模式類似于廣播電台,在訂閱釋出模式中Pub将消息發送到總線,所有的Sub收到來自總線的消息後,根據自己的條件來接收特定的消息。對應到salt中就是master将事件釋出到消息總線,minion訂閱并監聽事件,然後minion會檢視事件是否和自己比對以确定是否需要執行,比對條件就是多種主機比對方法。saltmaster和minion的通信過程中,會啟動監聽兩個端口,預設是4505和4506。

    4506的作用:Salt Master Ret接口,支援認證(auth)、檔案服務、結果收集等功能;

    4505的作用:Salt Master Pub接口,提供遠端執行指令發送功能。

    Salt minion啟動時從配置檔案中擷取master的位址,如果為域名,則進行解析。解析完成後,會連接配接master的4506(ret接口)進行key認證。認證通過,會擷取到master的publish_port(預設是4505),然手連接配接publish_port訂閱來自master pub接口任務。當master下發操作指令是,所有的minion都能接收到,然後minion會檢查本機是否比對。如果比對,則執行。執行完畢後,把結果發送到master的4506(ret接口)由master進行處理,指令發送通信完成是異步的,并且指令包很小。此外,這些指令包通過maqpack進行序列化後資料會進一步壓縮(Maqpack是一種高效的二進制序列化格式),是以salt的網絡負載非常低。

二、Saltstack的安裝

2.1 yum源安裝

下載下傳Centos6的epol源進行安裝:

<code>wget -O </code><code>/etc/yum</code><code>.repos.d</code><code>/epel</code><code>.repo http:</code><code>//mirrors</code><code>.aliyun.com</code><code>/repo/epel-6</code><code>.repo</code>

如果使用Centos7,可以下載下傳此epol源:

<code>wget -O </code><code>/etc/yum</code><code>.repos.d</code><code>/epel</code><code>.repo http:</code><code>//mirrors</code><code>.aliyun.com</code><code>/repo/epel-7</code><code>.repo</code>

安裝master端:

<code>yum </code><code>install</code> <code>salt-master</code>

啟動master端服務:

<code>/etc/init</code><code>.d</code><code>/salt-master</code> <code>start</code>

<a href="https://s4.51cto.com/oss/201711/22/43fd178ff2fc4e0b809cdd1474b4065c.png-wh_500x0-wm_3-wmp_4-s_3029019880.png" target="_blank"></a>

Agent安裝minion端:

<code>Yum </code><code>install</code> <code>salt-minion</code>

2.2 Agent簡單配置Saltstack

Agent指定master:

<code>vim </code><code>/etc/salt/mionion</code>

<code># resolved, then the minion will fail to start.</code>

<code>#master: salt</code>

<code>master: 192.168.39.135</code>

修改mionion的id号:

<code># clusters.</code>

<code>#id:</code>

<code>id</code><code>: Agent1</code>

注:id号用于唯一區分mionion的标示,可以不做指定,預設為主機名。

啟動minon服務:

<a href="https://s1.51cto.com/oss/201711/22/873ac98c4110b922c7a67abac2091985.png-wh_500x0-wm_3-wmp_4-s_3149570931.png" target="_blank"></a>

2.3 master授權mionion密鑰認證

master檢視認證請求:

<code># salt-key</code>

<a href="https://s4.51cto.com/oss/201711/22/efbb1f99534bb6dfcb20628e9f4ae489.png-wh_500x0-wm_3-wmp_4-s_604481073.png" target="_blank"></a>

master授權請求:

<code># salt-key -a centos-test1</code>

可以批量授權請求:

<code>[root@centos salt]</code><code># salt-key -A</code>

再次檢視請求,可以看到都以授權成功:

<a href="https://s3.51cto.com/oss/201711/22/5315774f7e5de67765b3f0c6ade9acd0.png-wh_500x0-wm_3-wmp_4-s_1935591706.png" target="_blank"></a>

進行測試,可以看到agent端資訊:

<a href="https://s4.51cto.com/oss/201711/22/fc16e9796a89da270f46749de6382689.png-wh_500x0-wm_3-wmp_4-s_3969053185.png" target="_blank"></a>

三、Saltstack的資料系統

Saltstack有兩個資料系統,分别是Grains和Pillar。本質上它們都是key value型的資料庫。

3.1 Grains

Grains是存儲在minion上的資料,minion啟動後就進行Grains計算。Grains是一種靜态資料,包括很多諸如作業系統、作業系統版本或CPU核心數量、記憶體大小等資料。這些資料不

經常變,即使有所變化重新開機Minion也會重新計算生成。Grains讓salt變得更加靈活。

Grains功能:1)資訊查詢 ;包括資産管理  2)用于目标選擇   3)配置管理中使用

3.1.1 資訊查詢(包括資産管理)

<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.ls  #列出ID為"centos-test1"的主機,grains所有項</code>

<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.items #列出主機的詳細資訊,可用于資産管理</code>

<code>[root@centos ~]</code><code># salt 'centos-test1*' grains.item host #查詢centos-test1的主機名</code>

<code>[root@centos ~]</code><code># salt '*' grains.item fqdn_ip4 #查詢左右主機的ip位址</code>

3.1.2 目标選擇

<code>[root@centos ~]</code><code># salt -G os:CentOS test.ping #對所有主機系統為"centos"的主機進行Ping測試</code>

<code>[root@centos ~]</code><code># salt -G os:CentOS cmd.run 'w' #對所有主機系統為“centos”的主機查詢負載狀态</code>

3.1.3 配置管理中的使用

方法一:

通過修改minion的配置檔案可以自定義Grains。

<code># vim /etc/salt/minion</code>

<code>#  cabinet: 13</code>

<code>#  cab_u: 14-15</code>

<code>grains:</code>

<code>   </code><code>roles:</code>

<code>     </code><code>- webserver</code>

<code>     </code><code>- memcache</code>

重新開機minion服務:

<code># /etc/init.d/salt-minion restart</code>

通過自定義的item,可以實作對所有角色為memche指令執行"date"指令

<code>[root@centos ~]</code><code># salt '*' grains.item roles #查詢所有主機的角色資訊</code>

<code>[root@centos ~]</code><code># salt -G 'roles:memcache' cmd.run 'date' #對所有主機roles為memcache的主機,執行"date"指令</code>

方法二:

也可以通過修改/etc/salt/grains檔案來實作。

<code># vim /etc/salt/grains</code>

<code>minion: host1</code>

<code>[root@centos ~]</code><code># salt -G 'minion:host1' cmd.run 'w'[object Object]</code>

修改/etc/salt/grains不重新開機服務的方法,重新整理指令如下(備注:方式一和方式二修改配置檔案,通過此指令都可以不用重新開機服務)

<code># salt '*' saltutil.sync_grains</code>

方法三:

Grains在top file中使用(Grains module方式)。

1)建立檔案系統路徑:

<code>[root@centos ~]</code><code># mkdir -p /srv/salt/</code>

2)修改master配置檔案指定top file檔案路徑

<code>[root@centos ~]</code><code># vim /etc/salt/master</code>

<code>#     - /srv/salt/prod/services</code>

<code>#     - /srv/salt/prod/states</code>

<code>#</code>

<code>file_roots:</code>

<code>  </code><code>base:</code>

<code>   </code><code>- </code><code>/srv/salt</code>

3) 編輯top file檔案

<code>[root@centos ~]</code><code># vim /srv/salt/top1.sls base:</code>

<code>base:</code>

<code>  </code><code>'web:nginx'</code><code>:</code>

<code>    </code><code>- match: grains  </code><code>#指定grains進行比對</code>

<code>    </code><code>- apache </code><code>#執行apache.sls</code>

#所有值為nginx的主機,執行apache的狀态

<code>[root@centos ~]</code><code># vim /srv/salt/apache.sls</code>

<code>apache-</code><code>install</code><code>:</code>

<code>  </code><code>pkg.installed:</code>

<code>    </code><code>- names:</code>

<code>      </code><code>- httpd</code>

<code>      </code><code>- httpd-devel</code>

<code>apache-service:</code>

<code>  </code><code>service.running:</code>

<code>    </code><code>- name: httpd</code>

<code>    </code><code>- </code><code>enable</code><code>: True</code>

<code>    </code><code>- reload: True</code>

<code>[root@centos ~]</code><code># salt '*' state.highstate  #執行[object Object]</code>

案例:

<code>/srv/salt/webserver</code><code>.sls</code>

<code>apache:                 </code><code># 标簽定義</code>

<code>  </code><code>pkg:                  </code><code># state declaration</code>

<code>    </code><code>- installed         </code><code># function declaration</code>

<code>第一行被稱為(ID declaration) 标簽定義,在這裡被定義為安裝包的名。注意:在不同發行版軟體包命名不同,比如 fedora 中叫httpd的包 Debian</code><code>/Ubuntu</code><code>中叫apache2</code>

<code>第二行被稱為(state declaration)狀态定義, 在這裡定義使用(pkg state module)</code>

<code>第三行被稱為(</code><code>function</code> <code>declaration)函數定義, 在這裡定義使用(pkg state module)調用 installed 函數</code>

3.2 Pillar

Grains很強大,但是其缺點是這些資料相對來說都是靜态資料。如果有變化的資料如何處理呢?這時我們就用到了pillar。pillar資料存儲在master上。指定的minion隻能看到自己pillar資料,其他的minion看不到任何pillar資料,這一點與狀态檔案正好相反。所有通過認證的minion都可以擷取狀态檔案,但是每隔minion卻都有自己的一套pillar資料,而且每台minion的pillar都進行了加密,是以很适用于敏感資料。

3.2.1 開啟pillar

現在saltstack已經預設關閉pillar,是以pillar功能需要開啟。

<code># the pillar called "master". This is used to set simple configurations in the</code>

<code># master config file that can then be used on minions.</code>

<code>pillar_opts: True</code>

<code>[root@centos ~]</code><code># service salt-master restart</code>

列出minion所有pillar的詳細資訊。

<code>[root@centos ~]</code><code># salt 'centos-test1' pillar.items</code>

3.2.2 定義pillar目錄

<code>#    - /srv/pillar</code>

<code>pillar_roots:</code>

<code>    </code><code>- </code><code>/srv/pillar</code>

<code>[root@centos ~]</code><code># mkdir -p /srv/pillar</code>

1) 建立一個pillar檔案(python jinjia2寫法)

<code>[root@centos ~]</code><code># vim /srv/pillar/apache.sls</code>

<code>{%</code><code>if</code> <code>grains [</code><code>'os'</code><code>] == </code><code>'CentOS'</code> <code>%}</code>

<code>apache: httpd</code>

<code>{% </code><code>elif</code> <code>grains[</code><code>'os'</code> <code>== </code><code>'Debian'</code><code>] %}</code>

<code>apache: apache2</code>

<code>{% endif %}</code>

2)建立top file檔案

<code>[root@centos ~]</code><code># vim /srv/pillar/top.sls</code>

<code>  </code><code>'*'</code><code>:</code>

<code>   </code><code>- apache</code>

#讓所有主機(*),讀取apachepillar

<code>[root@centos ~]</code><code># salt '*' saltutil.refresh_pillar  #執行重新整理pillar</code>

<code>[root@centos ~]</code><code># salt '*' pillar.items</code>

使用pillar定位主機:

<code>[root@centos ~]</code><code># salt -I 'apache:httpd' test.ping</code>

3.3 Grains和Pillar的不同

四、Saltstack遠端執行

4.1 遠端執行

在遠端主機上運作預定義的或任意的指令,亦稱為遠端執行,是salt的核心功能。了解子產品和傳回值,是遠端執行兩個關鍵要素。

Salt指令由三個主要部分構成:

<code>salt </code><code>'&lt;target&gt;'</code> <code>&lt;</code><code>function</code><code>&gt; [arguments]</code>

target部分允許你指定哪些minion應該運作執行. 預設的規則是使用glob比對minion id. 例如:

<code>salt </code><code>'*'</code> <code>test</code><code>.</code><code>ping</code>

<code>salt </code><code>'*.example.org'</code> <code>test</code><code>.</code><code>ping</code>

Targets可以使用Grains系統來通過minion的系統資訊進行過濾:

<code>salt -G </code><code>'os:Ubuntu'</code> <code>test</code><code>.</code><code>ping</code>

參見

<a href="http://docs.saltstack.cn/topics/targeting/grains.html">Grains系統</a>

ip位址或子網路遮罩進行檢測:

<code>salt -S </code><code>'192.168.39.200'</code> <code>test</code><code>.</code><code>ping</code>

Targets也可以使用正規表達式:

<code>salt -E </code><code>'virtmach[0-9]'</code> <code>test</code><code>.</code><code>ping</code>

Targets也可以指定清單:

<code>salt -L </code><code>'foo,bar,baz,quo'</code> <code>test</code><code>.</code><code>ping</code>

或者在一個指令中混合使用多target類型:

<code>salt -C </code><code>'G@os:Ubuntu an webser* or E@database.*'</code> <code>test</code><code>.</code><code>ping</code>

funcation是module提供的功能. Salt内置了大量有效的functions. 列出minions上的所有有效functions?

<code>salt </code><code>'*'</code> <code>sys.doc</code>

這裡有一些例子:

顯示目前所有有效的minions:

運作一個任意的shell指令:

<code>salt </code><code>'*'</code> <code>cmd.run </code><code>'uname -a'</code>

<a href="http://docs.saltstack.cn/ref/modules/all/index.html">所有子產品清單</a>

function通過空格來界定參數:

<code>salt </code><code>'*'</code> <code>cmd.exec_code python </code><code>'import sys; sys.version'</code>

可選的, 也支援keyword參數:

<code>salt </code><code>'*'</code> <code>pip.</code><code>install</code> <code>salt timeout=5 upgrade=True</code>

他們常常在 <code>kwargs=argument</code> form中.

4.2 salt常用子產品

下面指列舉service子產品使用方法:

<code>salt.modules.service.available(name)</code>

判斷指定服務是否存在,如果存在傳回True,否則傳回False。

<code>[root@centos ~]</code><code># salt '*' service.available sshd</code>

<code>centos-test2:</code>

<code>    </code><code>True</code>

<code>centos-test3:</code>

<code>centos-test1:</code>

<code>salt.modules.service.get_all()</code>

傳回所有服務可用的清單。

<code>[root@centos ~]</code><code># salt '*' service.get_all</code>

<code>    </code><code>- abrt-ccpp</code>

<code>    </code><code>- abrt-oops</code>

<code>    </code><code>- abrtd</code>

<code>    </code><code>- acpid</code>

<code>    </code><code>- atd</code>

<code>    </code><code>- auditd</code>

<code>    </code><code>- blk-availability</code>

<code>    </code><code>- control-alt-delete</code>

<code>    </code><code>- cpuspeed</code>

<code>    </code><code>- crond</code>

<code>    </code><code>- haldaemon</code>

<code>salt.modules.service.run(name, action)</code>

用動作運作指定的服務。

name --服務名 action --動作名稱,如start,stop,reload,restart。

<code># salt '*' service.run apache2 reload</code>

<code># salt '*' service.run postgresql initdb</code>

<code>salt.modules.service.start(name)</code>

啟動指定服務。

<code>[root@centos ~]</code><code># salt '*' service.start httpd</code>

<code>salt.modules.service.status(name)</code>

查詢指定服務狀态。服務啟動傳回True,服務未啟動傳回False。

<code>[root@centos ~]</code><code># salt '*' service.status httpd</code>

4.3 子產品的ACL(通路控制)

4.3.1 對系統使用者允許特定指令執行

1)修改相應目錄權限

<code>[root@centos ~]</code><code># chmod 755 /var/cache/salt /var/cache/salt/master /var/cache/salt/master/jobs /var/run/salt /var/run/salt/master/</code>

2)修改master配置檔案,開啟acl通路控制

<code>client_acl:</code>

<code>  </code><code>jerry:    </code><code>#使用者jerry</code>

<code>    </code><code>- </code><code>test</code><code>.</code><code>ping</code>  <code>#隻允許使用test.ping和network下所有方法</code>

<code>    </code><code>- network.*</code>

3)重新開機服務

<code>[root@centos ~]</code><code># /etc/init.d/salt-master restart</code>

測試:

4.3.2 指定使用者在某一台機器上執行特定指令

1)修改配置

<code>  </code><code>jerry:</code>

<code>    </code><code>- </code><code>test</code><code>.</code><code>ping</code>

<code>  </code><code>tom:  </code><code>#使用者</code>

<code>    </code><code>- centos-test1*: </code><code>#主機centos-test1</code>

<code>      </code><code>- </code><code>test</code><code>.</code><code>ping</code> <code>#test.ping指令</code>

2)重新開機服務

測試:

五、Saltstack配置管理

Saltstack包含一個健壯且靈活的配置管理架構,該架構建立在遠端執行核心上。這個架構執行的minion端,允許輕松,同時可配置成千上萬的主機,通過編寫特定于語言的狀态檔案得以實作。saltstack的配置管理提供了很多的“狀态子產品”用于實作不同配置管理的需求。以下是配置管理的連結以友善查詢:https://docs.saltstack.com/en/latest/topics/states/index.html

1)修改file_root檔案目錄

<code>[root@centos base]</code><code># vim /etc/salt/master </code>

<code>    </code><code>- </code><code>/srv/salt/base</code>

<code>  </code><code>test</code><code>:</code>

<code>    </code><code>- </code><code>/srv/salt/test</code>

<code>  </code><code>prod:</code>

<code>    </code><code>- </code><code>/srv/salt/prod</code>

2) 建立檔案目錄

<code>[root@centos base]</code><code># mkdir -p /srv/salt/base</code>

<code>[root@centos base]</code><code># mkdir -p /srv/salt/test</code>

<code>[root@centos base]</code><code># mkdir -p /srv/salt/prod</code>

<code>[root@centos base]</code><code># /etc/init.d/salt-master restart</code>

批量修改/etc/resolv.conf檔案:

<code>[root@centos ~]</code><code># cd /srv/salt/base</code>

<code>[root@centos base]</code><code># vim dns.sls</code>

<code>/etc/resolv</code><code>.conf:    </code><code>#标簽</code>

<code>  </code><code>file</code><code>.managed:     </code><code>#狀态子產品file的mamaged方法,用以實作</code>

<code>    </code><code>- </code><code>source</code><code>: salt:</code><code>//files/resolv</code><code>.conf  </code><code>#源檔案resolv.conf</code>

<code>    </code><code>- user: root    </code><code>#檔案使用者屬主</code>

<code>    </code><code>- group: root    </code><code>#檔案數組</code>

<code>    </code><code>- mode: 644    </code><code>#檔案權限</code>

檔案目錄狀态為:

resolv.conf檔案内容:

<code>[root@centos base]</code><code># more files/resolv.conf </code>

<code># Generated by NetworkManager</code>

<code>nameserver 192.168.39.2</code>

<code>[root@centos base]</code><code># salt '*' state.sls dns #執行dns狀态檔案</code>

也可以從top檔案上執行。

<code>[root@centos base]</code><code># vim top.sls </code>

<code>    </code><code>- dns</code>

<code>[root@centos base]</code><code># salt '*' state.highstate  #state進階狀态預設從top檔案中執行</code>

檢視minion端的resolv.conf檔案:

5.2 saltstack配置管理之YAML和jinjia

5.2.1 什麼是YAML?

YAML文法規則:

規則一:縮緊

1)yaml使用一個固定的縮緊風格表示水層結構關系。salt需要每個縮緊分别由兩個空格組成。

2)不要使用tabs。

規則二:冒号

YAML my_key: my_value

first_level dict_key:

  second_level dict_key: value_in_second_level_dict

IN Pyton {‘my_key’: ‘my_value’,

{

‘first_level_dict_key’:{

‘second_level_dict_key’: ‘value_in_second_level_dict’

}

規則三:短橫線

想要表示清單項:使用一個短橫杠加一個空格。多個項使用同樣的縮緊級别作為同一清單的一部分。

my_dictionary:

  - list_value_one

  - list_value_two

  - list_value_three

{‘my_dictionary’: [‘list_value_one’,’list_value_two’,’list_value_three’]}

5.2.2 什麼是jinja?

1.file狀态使用template參數

2.模版檔案裡面變量使用{{ 名稱 }} {{ PORT }}

3.變量清單

-defaults:

PORT:8080

4.Jinjia if-else 語句

{% if grains[‘fqdn’] == ‘lb-node1.unixhot.com’ %}

  — ROUTEID: haproxy_master

  - STATEID: master

{% elif grains[‘fedn’] == ‘lb-node2.unixhot.com’ %}

  - ROUTEID: haproxy_backup

  - STATEID: backup

  - PRIORITYID: 100

{% endif %}

5.2.2 變量的使用

以上一個示例需改resolv.conf為例

<code>[root@centos ~]</code><code># vim /srv/salt/base/dns.sls </code>

<code>/etc/resolv</code><code>.conf:</code>

<code>  </code><code>file</code><code>.managed:</code>

<code>    </code><code>- </code><code>source</code><code>: salt:</code><code>//files/resolv</code><code>.conf</code>

<code>    </code><code>- user: root</code>

<code>    </code><code>- group: root</code>

<code>    </code><code>- mode: 644</code>

<code>    </code><code>- template: jinja </code><code>#template指定為jinja模版</code>

<code>    </code><code>- defaults:</code>

<code>      </code><code>DNS_SERVER: 192.168.39.23 </code><code>#變量:預設值</code>

<code>[root@centos ~]</code><code># vim /srv/salt/base/files/resolv.conf </code>

<code>nameserver {{ DNS_SERVER }} </code><code>#{{ DNS_SERVER }} 作為變量,也可以使用單括号,這裡使用便于區分</code>

<code>[root@centos base]</code><code># salt '*' state.highstate #執行進行修改minions端配置</code>

可以看到已經修改完成。

參考資料:

<a href="https://docs.saltstack.com/en/latest/">https://docs.saltstack.com/en/latest/</a>

<a href="http://outofmemory.cn/saltstack/salt">http://outofmemory.cn/saltstack/salt</a>

本文轉自 SoulMio 51CTO部落格,原文連結:http://blog.51cto.com/bovin/1984115,如需轉載請自行聯系原作者