Ansible的Ad-Hoc(臨時命令)命令集配置詳解
簡介:
Ad-Hoc簡而言之是“臨時命令”,英文中作為形容詞有“特別的”,“臨時”的含義。
Ansible提供兩種完成任務方式:一種是Ad-Hoc命令集,即命令ansible,另外一種就是Ansible-playbook了,即命令Ansible-playbook。
Ad-Hoc適合解決一些簡單或者平時工作中臨時遇到的任務
Ansible-playbook適合解決複雜或需固化下來的任務
深入Ansible是從接觸Ansible-playbook開始的,靈活運用Ansible-playbook才能更好的體會到Ansible的強大所在。
Ad-Hoc命令集介紹
Ad-Hoc命令集由/usr/bin/ansible實現,其命令用法如下:
ansible <host-pattern> [options]
可用選項如下:
-v,--verbose:輸出更詳細的執行過程資訊,-vvv可得到執行過程所有資訊。 -i,PATH,--inventory(清單)=PATH:指定inventory(清單)資訊,預設/etc/ansible/hosts -f NUM,--forks=NUM:併發執行緒數,預設5個執行緒。 --private-key=PRIVATE_KEY_FILE:指定金鑰檔案。 -m NMAE,--module-name=NAME:指定執行使用的模組。 -M DIRECTORY,--module-path=DIRECTORY:指定模組存放路徑,預設/usr/share/ansible,也可以通過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組所有主機是否存活。
執行命令:
ansible proxy -f 5 -m ping
返回結果:
上述執行結果:
其中192.168.1.18是指命令執行的主機,Success表示命令執行成功,">>{}"表示詳細返回結果如下。
"changed":false 表示沒有對主機做變更"ping":"pong"表示執行了ping命令返回結果為pong。
(2.)返回proxy組所有主機的hostname,並列印最詳細的執行過程到標準輸出。
執行命令:
ansible proxy -s -m command -a 'hostname' -vvv
上述執行結果:
ESTABLISH CONNECTION FOR USER:root :遠端主機192.168.1.18監聽使用者root的22號埠
REMOTE_MODULE command hostname :遠端執行命令hostname
"/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1537154337.4-134606313491356 && echo $HOME/.ansible/tmp/ansible-tmp-1537154337.4-134606313491356'"] :生成臨時目錄用於存放Ansible遠端執行指令碼。
PUT /tmp/tmp4f_9zu TO /root/.ansible/tmp/ansible-tmp-1537154337.4-134606313491356/command :改名臨時指令碼並存放至臨時目錄。
EXEC ['ssh', '-C', '-tt', '-q', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o', 'Port=22', '-o', 'IdentityFile="/root/.ssh/id_rsa_storm1"', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'ConnectTimeout=10', '192.168.1.18', u"/bin/sh -c 'LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1537154337.4-134606313491356/command; rm -rf /root/.ansible/tmp/ansible-tmp-1537154337.4-134606313491356/ >/dev/null 2>&1'"] :使用sudo方式並以Python指令碼方式執行命令。
192.168.1.18 | success | rc=0 >> :返回結果成功。
(3.)對192.168.1.18伺服器以root執行sleep20,設定最大連線超時時間時長為2s,且設定為後臺執行模式,執行過程沒2s輸出一次進度,如5s還未執行完則終止該任務。
執行命令:
time ansible 192.168.1.18 -B 5 -P 2 -T 2 -m command -a 'sleep 20' -u root
執行結果如下:
第一行:background launch...表示使用-B使該命令後臺執行。
下面每隔2s輸出一次執行進度
<job 628451417226.4601> polling, 3s remaining 表示執行時長剩餘3s
下面每隔2s輸出一次執行進度
<job 628451417226.4601> polling, 1s remaining 表示執行時長剩餘1s
real 0m55.664s 程式執行總時長 user 0m0.269s 系統使用者層執行時長 sys 0m0.118s 系統核心層執行時長
通過Ad-Hoc檢視系統設定
接下來通過df、free命令檢視系統設定,通過Ad-Hoc實現。
(1.)批量檢視apps組所有主機的磁碟容量(使用command模組)。
執行命令:
ansible apps -a "df -lh"
返回結果如下:
success表示執行成功
(2.)批量檢視遠端主機記憶體使用情況(shell模組)。
ansible apps -m shell -a "free -m "
返回結果如下:
通過Ad-Hoc研究Ansible的併發特性
ansible和Ansible-playbook預設會fork 5個執行緒併發執行命令,但在實際工作中,如果主機數量眾多,Ansible併發5個執行緒是遠不能滿足企業所需的。
接下來我們定義[apps]組,多次執行同樣的Ad-Hoc命令來檢視其返回的結果。
(1.)定義[apps]組,編輯/etc/ansible/hosts的配置
[apps]
192.168.1.18
192.168.1.27
192.168.1.29
192.168.1.30
(2.)多次執行Ansible命令,執行命令如下:
ansible apps -m ping -f 3
對比返回結果:
上述執行的結果分析如下:
同樣的命令多次執行,但每次的輸出結果都不一定一樣。
輸出結果是不是按照/etc/ansible/hosts中[apps]定義的主機順序輸出。
如果主機數量很多,我們需要調大執行緒數,該如何操作呢?這裡ansible為我們提供了便捷的選項 ,-f指定執行緒數。
Ansible使用multiprocessing管理多執行緒。
通過Ad-Hoc研究Ansible的模組使用
接下來為大家介紹Ad-Hoc的模組使用。另外,Ansible也提供了類似於man功能的help說明工具ansible-doc。
正式學習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
執行結果:
(2.)以yum模組為例,我們希望獲取yum模組的HELP說明。
執行命令:
ansible-doc yum
執行結果:
其他模組HELP說明以此類推。下面通過Ansible內建模組來完成一些具體工作。
1.安裝httpd服務並檢視服務的版本號
(1.)安裝httpd服務
執行命令:
ansible apps -m yum -a 'name=httpd state=present'
返回結果如下:
其中:
changed:主機是否有變更,True為有;false為沒有(第一次執行或事先沒有安裝,返回值一般是True,否則為false)。
msg:安裝過程資訊
rc:0,resultcode:結果返回碼,非0返回碼往往是紅色並且錯誤的返回,非常明顯。
(2.).檢視服務版本號
執行命令:
ansible apps -m command -a '/usr/sbin/httpd -V'
返回結果如下:
部分執行結果解釋:
192.168.1.18:表示命令執行的物件
success:表示命令執行的返回狀態為成功狀態。
rc=0:表示命令執行的狀態碼為0
>>:該符號後返回的所有內容為執行/usr/sbin/httpd -V命令返回的資訊。
2.為所有伺服器安裝ntp服務,並設定為開機自啟動。
(1.)安裝ntp服務
執行命令:
ansible apps -s -m yum -a "name=ntp state=present"
返回結果如下:
(2.)啟動ntp服務,並設定為開機自啟動。
執行命令:
ansible apps -m service -a "name=ntp state=started enabled=yes"
執行結果如下:
返回的結果不再一一介紹了,相信已經懂了。
Ad-Hoc組管理和特定主機變更
Ad-Hoc組定義:Ad-Hoc的組功能定義在Inventory(清單)檔案中,預設路徑是/etc/ansible/hosts,書寫格式遵循INI風格,中括號中的字元為組名。可以將同一個主機名稱之後使用冒號加埠號來標明。
接下來即將使用Ansible搭建一套完整的架構應用去學習Ad-Hoc的組管理方式。
本次架構規劃了前端Proxy、web Service和後面DB一套完整應用,下面便是架構拓撲圖:
如上圖所示是簡化後的網際網路web服務架構, 使用者請求通過proxy轉發至後端WebServers響應,通過NoSQL服務緩衝後,最終將請求傳送到DB這樣的一個過程。
準備部署環境如下:
定義 Inventorycat(清單) /etc/ansible/hosts:
[proxy]
192.168.1.18
[app]
192.168.1.27
192.168.1.29
[nosql]
192.168.1.30
[db]
192.168.1.19
應用分佈如下:
[proxy]組:Nginx
[app]組:Nginx+PHP+Django
[nosql]組:Redis
[db]組:Mariadb
Ad-Hoc配置管理:配置Proxy與Web Servers實踐
接下來我們按Proxy、WebServers 依次順序部署應用。
(1.)Ad-Hoc配置管理Proxy(即Nginx)
小提示:
首先配置好對方nginx的yum源讓主機能夠安裝上nginx服務。
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
利用ansible安裝Nginx執行命令:
ansible proxy -m yum -a "name=nginx state=present"
安裝結果:
部分執行結果解釋:
changed:true,//表示本次命令對執行的目標有變更,True為第一次安裝,如再執行一次則為false,表示執行的目標沒有變更,這裡的false和true不代表該命令執行成功或失敗,只是表示執行目標是否被變更。
rc:0,//resultcode的簡寫,表示命令執行結果返回狀態,非0均為異常,命令執行失敗
results:[ //執行結果資訊返回
安裝完Nginx讓我們來檢查一下Nginx是否安裝成功,可以執行如下命令:
ansible proxy -m command -a "nginx -v"
如果安裝成功則顯示如下結果:
如上所示是Nginx就安裝好了,其實通過Ansible的YUM模組來安裝Nginx有很多種方法,通過網路YUM源安裝是其中的一種,
那麼還可以從本地YUM源安裝,以及通過去倉庫拉去相關服務的源也是可以的。
(2.)Ad-Hoc配置管理Web Servers
安裝完了Nginx前端代理服務,同時Web Servers需要部署Nginx 、PHP和Django,其中Nginx、PHP依然通過YUM模組實現,Django推薦使用PIP或easy_install方式。
小提示:因為斷電原因後面的ip有所變化,不過一樣好理解!!!
同樣和之前安裝的Nginx服務一樣要把Nginx、PHP的YUM源配置上
Nginx、PHP安裝命令如下:
ansible app -m yum -a "name=nginx state=present"
ansible app -m yum -a "name=php state=present"
顯示Nginx安裝執行結果:
顯示PHP安裝執行結果:
Django命令安裝如下:
(1.)安裝MySQL-python和python-setuptools依賴包。
ansible app -m yum -a "name=MySQL-python state=present"
ansible app -m yum -a "name=php state=present"
安裝MySQL-python顯示結果如下:
安裝python-setuptools顯示如下:
(2.)安裝Django:
ansible app -m pip -a "name=django state=present"
安裝顯示結果:
檢查Django安裝是否正常 ,執行命令如下:
ansible app -m command -a "python -c 'import django; print django.get_version()'"
顯示結果如下:
如果上述安裝報錯請檢查python版本,其中Django依賴Python2.7+版本。
截止目前,proxy & webservers部署完畢了。
Ad-Hoc配置後端:配置NoSQL與Database Servers實踐
接下來我們使用類似的方法配置NoSQL和DB服務。
Redis安裝命令如下:
ansible nosql -m yum -a "name=redis state=present"
顯示結果如下:
Redis安裝完,進行檢檢視安裝是否正常,執行命令如下:
ansible nosql -m command -a "redis-cli --version"
顯示版本結果如下:
安裝Mariadb,具體操作步驟如下:
(1.)新增yum源,vim編輯/etc/yum.repos.d/mariadb.repo新增如下內容:
[mariadb]
name = Mariadb
baseurl=http://yum.mariadb.org/10.1/centos/7.2/x86_64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
(2.)安裝MariaDB-server,執行如下命令:
ansible db -m yum -a "name=MariaDB-server state=present"
顯示結果如下:
(3.)安裝MariaDB-client,執行命令如下:
ansible db -m yum -a "name=MariaDB-client state=present"
顯示結果如下:
截止目前,所有的應用成功部署完畢。
Ad-Hoc特定主機變更
前面我們通過搭建了一套主流web應用框架熟悉了Ansible的組管理,接下來為大家介紹如何針對特定伺服器做為變更。
Ansible有多種方式實現針對特定主機做變更。
(1.)--limit:通過 --limit引數限定主機做變更。
在APP組啟動192.168.1.19的NTP服務,執行下列命令檢視啟動後的NTP服務的狀態:
ansible app -m command -a "systemctl status ntpd.service" --limit "192.168.1.19"
顯示結果如下:
(2.)指定IP:通過指定具體IP限定主機做變更。
啟動192.168.1.19的NTP服務,執行下列命令檢視啟動後的NTP服務的狀態:
ansible 192.168.1.19 -m command -a "systemctl status ntpd.service"
顯示結果如下:
(3.)用 “:”做分隔符,指定多臺機器做變更。
啟動192.168.1.19和192.168.1.14的NTP服務,執行下列命令檢視啟動後的NTP服務的狀態:
ansible "192.168.1.14:192.168.1.19" -m command -a "systemctl status ntpd.service"
顯示結果如下:
(4.)通過“*”泛匹配,更靈活地針對多臺主機做變更。
啟動192.168.1.*所有主機的NTP服務,執行下列命令檢視啟動後的NTP服務的狀態:
ansible 192.168.1.* -m command -a "systemctl status ntpd.service"
顯示結果如下:
到目前為止Ad-Hoc組管理 及特定主機變更我們已經掌握,這對靈活管理海量伺服器有很大幫助。
關於組及指定主機管理介紹到此結束。接下來為大家介紹的是Ad-Hoc基於使用者管理。
Ad-Hoc使用者與組管理
ansible系統使用者模組有如下兩個:
Linux系統使用者管理:user
windows系統使用者管理:win_user
Linux使用者管理:
User模組功能諸多,模組屬性如下:
append yes:增量新增group no:全量變更group,只設置groups指定的group組。
comment: 可選設定使用者賬戶的描述(又名GECOS)
createhome:預設選項yes,當建立使用者期時或家目錄不存在時 為使用者建立HOME目錄。
expires(1.9版本增加):1.9版本的新增功能,使用者過期時間,不支援的平臺該引數將被忽略,現在支援Linux和FreeBSD
force:強制,當和state=absent結合使用時,效果等同於userdel --force
generate_ssh_key: 是否生成SSH key,不會覆蓋已有的SSH key
group :(可選)設定使用者屬組
groups:設定使用者附加群組,使用逗號分隔多個群組,如果引數為空(即‘groups=’),則刪除使用者所有附加組(屬組不受影響)
home:(可選)設定使用者家目錄
login_class:(可選)設定FreeBSD、OPenBSD、NetBSD系統的使用者登入class
move_home:如設定為yes,結合使用home=,臨時遷移使用者家目錄到特定目錄。
name:使用者名稱
non_unique:(可選)和-u結合使用,允許改變使用者ID為非唯一值。
password:(可選)設定使用者密碼為該項指定的密碼(加密後的密碼)
remove:結合state=absent使用相當於userdel --remove
seuser(2.1版本增加):(可選)設定seuser型別啟用SELinux
shell :(可選)設定使用者shell
skeleton:(可選)設定使用者的skel目錄,需和createhome引數結合使用。
ssh_key_bits:(可選)指定生成的SSH key加密位數。
ssh_key_comment:(預設值:ansible-generated on $HOSTNAME)(可選)定義SSH key註釋
ssh_key_file:(預設值.ssh/id_rsa)(可選)指定SSH key 檔名,如果該檔名是相對路徑,則預設路徑為使用者家目錄。
ssh_key_passphrase:設定SSH key密碼,如果沒有提供密碼,則預設沒有加密。
ssh_key_type:(可選)設定SSH Key 型別,具體可用的SSH key型別取決於目標主機
state:present Present:新建(使存在)使用者,absent:刪除使用者
system:當建立新賬戶時,該選項為yes,為使用者設定系統賬戶,該設定對已經存在的使用者無效。
uid:(可選)設定使用者UID
update_password(1.3版本增加):always:只有當密碼不相同時才會更新密碼,on_create:只為新使用者設定密碼。
接下來為大家介紹使用者相關的五大場景應用,以供參考。
場景1:新增使用者
需求描述:新增使用者dba,使用BASH Shell,附加組為admins,dbagroup,家目錄為/home/dba/。
該場景中我們可以掌握如下技能點:
(1.)groups設定:groups=使用者組1,使用者組2......
(2.)增量新增屬組:append=yes
(3.)表名屬組狀態為新建:state=present
執行如下命令:
ansible db -m user -a "name=dba shell=/bin/bash groups=admins,dbagroup append=yes home=/home/dba/ state=present"
返回結果如下:
場景2:修改使用者屬組
需求描述:修改DBA附件組為dbagroups(即刪除admins組許可權)。
該場景中我們可以掌握如下技能點。
全量變更屬組資訊:append=no
執行命令如下:
ansible db -m user -a "name=dba groups=dbagroup append=no"
返回結果如下:
提示:刪除admins組許可權的命令中append值為no。另外,細心的朋友會發現,新增使用者時,ansible預設為使用者新增使用者組(primary group)。
場景3:修改使用者屬性
需求描述:設定dba使用者的過期時間為2016/6/1 18:00:00(UNIXTIME:1464775200)。
該場景中我們可以掌握如下技能點。
(1.)設定使用者登入過期時間:expire=1464775200
(2.)UNIX時間轉換:2016/6/1 18:00:00需轉換為UNIXTIME格式(不做介紹,請自行百度)
執行如下命令:
ansible db -m user -a "name=dba expires=1464775200"
這樣,我們已經完成了DBA使用者的過期時間設定。
場景4:刪除使用者
需求描述:刪除使用者DBA,並刪除其家目錄和郵件列表。
該場景中我們可以掌握如下技能點:
(1.)表明屬組狀態為刪除:state=absent
(2.)設定remove=yes:remove=yes
執行命令如下:
ansible db -m user -a "name=dba state=absent remove=yes"
返回顯示結果如下:
結果檢查:到對應主機使用root使用者檢視/etc/passwd是否存在dba使用者。或執行命令id dba確認是否有返回結果。
場景5:變更使用者密碼
需求描述:設定系統使用者tom的密碼為redhat123
執行命令如下:
ansible db -m user -a "name=tom shell=/bin/bash password=to46pW3GOukvA update_password=always"
顯示結果如下:
注意:password後面的密碼並非真正的密碼。官網上介紹了兩種密碼加密方式。
方式1:使用命令mkpasswd生成密碼
(1.)查詢安裝包名稱
執行命令如下:
yum whatprovides */mkpasswd
執行結果如下:
(2.)安裝軟體包
執行命令如下:
yum -y install expect
顯示結果如下:
(3.)使用mkpasswd生成密碼。
執行如下命令:
mkpasswd --method=SHA-512
方式2:使用Python的passlib、getpass庫生成密碼。
(1.)安裝passlib(Python版本建議2.7以上)
執行如下命令:
pip install passlib
執行顯示結果:
(2.)生成密碼
python3.x系列版本請使用如下命令(sha512加密演算法)。
python -c "from passlib.hash import sha512_crypt; import getpass; print (sha512_crypt.encrypt(getpass.getpass()))"
python3.x系列版本請使用如下命令(普通加密演算法)。
python -c 'import crypt; print (crypt.crypt("redhat123","dba"))'
python2.x系列版本請使用如下命令(sha512加密演算法)。
python -c "from passlib.hash import sha512_crypt; import getpass ; print sha512_crypt.encrypt(getpass.getpass())"
python2.x系列版本請使用如下命令(普通加密演算法)。
python -c 'import crypt; print (crypt.crypt("redhat123","dba"))'
應用層使用者管理
以MySQL使用者管理為例。
新增MySQL使用者stanley,設定登入密碼為[email protected],對zabbix.*表有ALL許可權。
執行如下命令:
ansible db -m mysql_user -a 'login_host=localhost login_password=magedu login_user=root name=stanley [email protected] priv=zabbix.*:ALL state=present'
登入驗證步驟如下:
(1.)在MySQL伺服器上進行測試登入
MySQL -u stanley -p [email protected]
(2.)執行如下命令,驗證許可權是否正確:
show grants for 'stanley'@'localhost';