本節書摘來自華章出版社《ansible權威指南》一書中的第3章,第3.2節,作者 李松濤 魏 巍 甘 捷 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
3.2 ad-hoc指令集介紹
本節介紹通過ad-hoc指令集檢視系統設定,通過ad-hoc研究ansible的并發特性,通過ad-hoc研究ansible的子產品使用。俗話說,磨刀不誤砍柴工。開始之前做一些簡單的初始化檢查,如系統時間正确與否、磁盤容量是否充足等,是很有必要的。
在實際工作中,很多“詭異”問題迫使我們花費大量時間排查,最終卻發現是非常簡單的基礎環境問題導緻的。這其實還是挺常見的,不論對新手還是老鳥均如此,謹記!
我們前面做的系統時間正确與否、磁盤容量是否充足等工作,其實linux下是有開源工具可以幫助我們自動監控的。這裡也為大家推薦幾款linux下耳熟能詳的監控工具,如zabbix、nagios、cacti、falcon、cat等。
3.2.1 ad-hoc指令集用法簡介
本節我們介紹ad-hoc指令集用法。ad-hoc指令集由usrbinansible實作,其指令用法如下:
ansible
host-pattern [options]
可用選項如下。
-v, --verbose:輸出更詳細的執行過程資訊,-vvv可得到執行過程所有資訊。
-i path,
--inventory=path:指定inventory資訊,預設etcansiblehosts。
-f num,
--forks=num:并發線程數,預設5個線程。
--private-key=private_key_file:指定密鑰檔案。
-m name,
--module-name=name:指定執行使用的子產品。
-m directory,
--module-path=directory:指定子產品存放路徑,預設usrshareansible,也可以通過ansible_library設定預設路徑。
-a 'arguments',
--args='arguments':子產品參數。
-k, --ask-pass
ssh:認證密碼。
-k,
--ask-sudo-pass sudo:使用者的密碼(--sudo時使用)。
-o, --one-line:标準輸出至一行。
-s, --sudo:相當于linux系統下的sudo指令。
-t directory,
--tree=directory:輸出資訊至directory目錄下,結果檔案以遠端主機名命名。
-t seconds,
--timeout=seconds:指定連接配接遠端主機的最大逾時,機關是秒。
-b num,
--background=num:背景執行指令,超num秒後中止正在執行的任務。
-p num,
--poll=num:定期傳回背景任務進度。
-u username,
--user=username:指定遠端主機以username運作指令。
-u
sudo_username, --sudo-user=sudo_username:使用sudo,相當于linux下的sudo指令。
-c connection,
--connection=connection:指定連接配接方式,可用選項paramiko (ssh)、ssh、local,local方式常用于crontab和kickstarts。
-l subset,
--limit=subset:指定運作主機。
-l ~regex, --limit=~regex:指定運作主機(正則)。
--list-hosts:列出符合條件的主機清單,不執行任何指令。
下面的示例有助于加深對上述内容的了解。
情景1:檢查proxy組所有主機是否存活。
執行指令:
proxy –f 5 –m ping
傳回結果如圖3-1所示。

執行結果诠釋:
192.168.37.159 success
{
changed false,
ping pong
}
其中192.168.37.159是指指令執行的主機,success表示指令執行成功,“ {}”表示詳細傳回結果如下。“changed
false”表示沒有對主機做變更,“ping
pong”表示執行了ping指令傳回結果為pong。
情景2:傳回proxy組所有主機的hostname,并列印最詳細的執行過程到标準輸出。
ansible proxy -s
-m command -a 'hostname' -vvv
傳回結果如圖3-2所示。
192.168.37.159
establish connection for user root on port 22 to 192.168.37.159 # 遠端主機192.168.37.159監聽root使用者的22号端口
remote_module command hostname # 遠端執行指令hostname
exec binsh -c 'mkdir -p $home.ansibletmpansible-tmp-1455684626.83-94958346638443
&& echo $home.ansibletmpansible-tmp-1455684626.83-94958346638443' # 生成臨時目錄用于存放ansible遠端執行腳本
put tmptmp5sawsq to
root.ansibletmpansible-tmp-1455684626.83-94958346638443command # 改名臨時腳本并存放至臨時目錄
exec binsh -c 'sudo -k && sudo -h -s -p [sudo via ansible,
key=urvzacjxvaagwvlrywymxpxfhjkirkqb] password
-u root binsh -c '''echo
become-success-urvzacjxvaagwvlrywymxpxfhjkirkqb; lang=c lc_ctype=c usrbinpython
root.ansibletmpansible-tmp-1455684626.83-94958346638443command; rm -rf
root.ansibletmpansible-tmp-1455684626.83-94958346638443 devnull 2&1'''' # 使用sudo方式并以python腳本方式執行指令
rc=0 # 傳回結果為success,coderesult為0
linuxlst # 傳回的指令傳回結果如下
使用-vvv參數可以清楚地了解ansible指令執行流程,如圖3-3所示。
情景3:列出web組所有主機清單。
ansible web
--list
傳回結果如下:
10.3.33.21
10.3.33.23
--list選項列出web組所有主機清單資訊,web組中包括 10.3.33.21 和 10.3.33.23兩台主機
接下來我們模拟較為複雜的場景。
情景4:對10.21.40.61伺服器以root執行sleep 20,設定最大連接配接逾時時長為2s,且設定為背景運作模式,執行過程每2s輸出一次進度,如5s還未執行完則終止該任務。
time指令可省,為友善觀察結果,這裡使用time指令檢視執行時長
time ansible
10.21.40.61 -b 5 -p 2 -t 2 -m command -a 'sleep 20' -u root
傳回結果如圖3-4所示。
第1行:[warning]不用理會,需更新gmp,該提醒不影響指令傳回結果
第2行:background
launch...表示使用-b使該指令背景運作
下面每隔2s輸出一次執行進度
job
182625384959.32339 polling on 10.21.40.61, 3s remaining表示執行時長剩餘3s
182625384959.32339 polling on 10.21.40.61, 1s remaining表示執行時長剩餘1s
real 0m10.268s程式執行總時長
user 0m1.898s系統使用者層執行時長
sys 0m0.163s系統核心層執行時長
細心的朋友會發現,我們sleep 20表示暫停 20s,即該指令最少執行時長為20s,但為什麼real程式實際運作時長隻有10s呢?這就是-b選項的意義了,如果超過其指定時間則終止正在執行的任務(但real為什麼是10.268s而不是5.268s,經筆者實測,-b功能生效但時間不精确,正式使用前請多測試)。
以上為ad-hoc指令集的用法說明,後面的章節我們會通過更複雜的執行個體深入了解其功能。
3.2.2 通過ad-hoc檢視系統設定
3.2.1節為大家介紹了ad-hoc的指令集用法,本節我們通過df、free指令檢視系統設定,但是是通過ad-hoc實作的,在此過程中幫助大家了解ansible。我們模拟如下兩個場景。
情景1:批量檢視apps組所有主機的磁盤容量(使用command子產品)。
ansible apps -a
df -lh
192.168.37.130 success
rc=0
filesystem size used avail use% mounted on
devmappervg_linuxlst-lv_root
19g 3.6g
14g 21%
tmpfs 123m 0
123m 0% devshm
devsda1 485m 29m
431m 7% boot
192.168.37.155 success
filesystem size used avail use% mounted on
devmappervg_linuxlst-lv_root 18g
4.9g 12g 30%
tmpfs 144m 0
144m 0% devshm
devsda1 485m 33m
427m 8% boot
192.168.37.142 success
5.4g 12g 33%
tmpfs 144m 0
192.168.37.156 success
devmappervg_linuxlst-lv_root 8.4g
6.4g 1.6g 81%
tmpfs 140m 0
140m 0% devshm
devsda1 485m 35m
426m 8% boot
devsdb5 20g 3.0g
16g 16% data2
以192.168.37.130的傳回為例,success表示指令執行成功,rc=0表示resultcode=0,即指令傳回結果,傳回碼為0,表示指令執行成功,後面跟的内容相當于在主機本地執行df –lh後的結果傳回。
情景2:批量檢視遠端主機記憶體使用情況(shell子產品)。
ansible apps -m
shell -a free -m
total used free
shared buffers cached
mem 286
282 4 0 34 119
-+
bufferscache 128 158
swap 2015 668 1347
mem 244 188 56 0 30 101
bufferscache 56 187
swap 1023 0 1023
mem 286 217 69 0 84 63
bufferscache 68 218
swap 2015 0 2015
mem 279 251 28 0 29 33
bufferscache 188 91
swap 1023 22 1001
以192.168.37.142的傳回為例,success表示指令執行成功,rc=0表示resultcode=0,即指令傳回結果,傳回碼為0,表示指令執行成功,後面跟的内容相當于在主機本地執行free-m後的結果傳回。
通過上面兩個場景的示例相信大家對ad-hoc的用法有一定的了解,接下來的章節我們進一步學習ansible的并發特性。
3.2.3 通過ad-hoc研究ansible的并發特性
如3.2.1節所講,ansible和ansible-playbook預設會fork 5個線程并發執行指令,但在實際工作中,如果主機數量衆多,ansible并發5個線程是遠不能滿足企業所需的,是以本節介紹ansible的并發特性。我們通過如下測試來更深入地了解ansible的并發工作模式。
場景如下:我們定義[apps]組,多次執行同樣的ad-hoc指令來檢視其傳回的結果。
以下是執行步驟。
步驟1:定義[apps]組,編輯etcansiblehosts的配置。
執行指令vi etcansiblehosts,鍵入i進入vi編輯模式,跳轉到檔案最末尾,添加如下配置:
[apps]
192.168.37.130
192.168.37.155
192.168.37.142
192.168.37.156
步驟2:多次執行ansible指令,執行指令如下:
ping -f 3
步驟3:對比傳回結果,如表3-1所示。
表3-1 傳回結果對比
第1次傳回結果 第2次傳回結果
changed false,
} 192.168.37.130 success
傳回結果分析如下:
1)同樣的指令多次執行,但每次的輸出結果都不一定一樣。
2)輸出結果不是按照etcansiblehosts中[apps]定義的主機順序輸出。
3)結果輸出基本上遵循每次輸出3條記錄(線程池始終保持3個線程,是以這裡如果每次輸出小于等于3都是正常的)。
通過上面的實驗我們對ansible的并發性有了概念性的了解。回到前面的問題,企業實際應用中,如主機數量很多,我們需調大線程數,該如何操作呢?這裡ansible為我們提供了便捷的選項,-f指定線程數,如-f 1表示并發啟動一個線程,-f 10則表示同時啟動10個線程并發執行指令。其實檢視源碼可知,ansible使用multiprocessing管理多線程。
單台主機的性能始終有限,大家根據自己機器實際的硬體配置做調整,建議并發數配置的cpu核數偶數倍就好。如4cores
8gb的伺服器,建議最多并發20個線程。關于ansible的性能,後面章節會為大家介紹ansible的加速模式。
3.2.4 通過ad-hoc研究ansible的子產品使用
前面的章節為大家詳細介紹了ad-hoc的指令集使用方法及其并發特性等,那麼,ansible究竟有多少現成功能可供大家使用呢?本節來為大家介紹ad-hoc的子產品使用。
截至本篇編寫時(2016-2-11),官方呈現的所有可用子產品為468個(2016-8-19所有可用子產品為622個,短短6個月增加了154個,可見ansible的發展速度),所有子產品官方也做了詳盡的功能分類。明細可參考官方連結。另外,ansible也提供了類似于man功能的help說明工具ansible-doc,直接按Enter鍵或輸入-h顯示功能用法。它和linux系統下的man指令一樣重要,正式學習ansible子產品使用前,有必要先了解ansible-doc用法。
指令用法:
ansible-doc
[options] [module...]
--version:顯示工具版本号。
-h, --help:顯示該help說明。
-m module_path,
--module-path=module_path:指定ansible子產品的預設加載目錄。
-l, --list:列出所有可用子產品。
-s, --snippet:隻顯示playbook說明的代碼段。
-v:等同于—version,顯示工具版本号。
下面我們看些簡單的示例。
情景1:顯示所有可用子產品。
ansible-doc –l
a10_server manage a10 networks
axsoftaxthundervthunder devices
a10_service_group manage a10 networks
a10_virtual_server manage a10 networks
acl sets and retrieves
file acl information.
add_host add a host (and
alternatively a group) to the ansible-playboo...
airbrake_deployment notify airbrake about app
deployments
alternatives manages alternative programs
for common commands
apache2_module enablesdisables a module of the
apache2 webserver
apt manages apt-packages
apt_key add or remove an apt key
apt_repository add and remove apt repositories
apt_rpmapt_rpm
package manager
arista_interface manage physical ethernet
interfaces
arista_l2interface manage layer 2 interfaces
arista_lag manage port channel (lag)
arista_vlan manage vlan resources
assemble assembles a configuration
file from fragments
…
情景2:以yum子產品為例,我們希望擷取yum子產品的help說明。
ansible-doc yum
yum
installs, upgrade, removes, and lists
packages and groups with the
`yum' package manager.
options (= is
mandatory)
- conf_file
the remote yum configuration file to
use for the transaction.
[default none]
其他子產品help說明以此類推即可。下面通過ansible内置子產品來完成一些具體工作。
【示例1】安裝redhat-lsb并檢視伺服器系統版本号。
步驟1:安裝redhat-lsb。
yum -a 'name=redhat-lsb state=present'
msg ,
rc 0,
results [
redhat-lsb-4.0-7.el6.centos.i686
providing redhat-lsb is already installed
]
其中:
changed:主機是否有變更,true為有;false為沒有(第1次運作或事先沒有安裝,傳回值一般是true,否則為false)。
msg:安裝過程資訊。
rc 0, resultcode:結果傳回碼,非0傳回碼往往是紅色并且錯誤的傳回,非常明顯。
步驟2:檢視系統版本号。
command -a 'lsb_release -a'
version
base-4.0-ia32base-4.0-noarchcore-4.0-ia32core-4.0-noarchgraph
lsb
ics-4.0-ia32graphics-4.0-noarchprinting-4.0-ia32printing-4.0-noarch
distributor id
centos
description centos release 6.5 (final)
release 6.5
codename final
部分執行結果诠釋:
192.168.37.155:表示指令執行的對象。
success:表示指令執行的傳回狀态為成功狀态。
rc=0:表示指令執行的狀态碼為0。
:該符号後傳回的所有内容為執行lsb_release –a指令傳回的資訊。
lsb version:表示該系統的核心版本資訊。
distributor id:表示發行廠商。
description:表示版本簡要資訊。
release:表示該系統的發行版本号。
codename:表示發行版本代号。
【示例2】為所有伺服器安裝ntp服務,并設定為開機啟動。
步驟1:安裝ntp服務。
ansible apps -s
-m yum -a name=ntp state=present
步驟2:啟動ntp服務,并設定為開機啟動。
service -a name=ntpd state=started enabled=yes
傳回的結果不再一一為大家列舉出來,相信上面那麼多的示例,大家對如何判斷結果是否正确能夠了解了。
如linux所有指令的用法一樣,我們隻能記住日常工作中最常用到的那些,另外那些不常用的指令用法我們隻需要知道如何快速擷取它們的用法即可。linux系統為我們提供了man工具來快速擷取所需。ansible-doc則等同于 man 的功能和作用,這樣解釋相信大家會更容易了解其重要性。