1. 程式人生 > >Ansible的Ad-Hoc(臨時命令)命令集配置詳解

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';