Ansible基礎元素介紹
2.1 Ansible目錄結構介紹
Ansible是開源工具,這個開發過程或二次開發均遵循GPL協議,所以所有原始碼均可見。作為一款日常工作所需的核心軟體,我們有必要知道期目錄分佈及各目錄功能。通過如下命令可以獲取Ansible所有檔案存放目錄:
#rpm -ql ansible
該命令輸出內容較多,大致分為如下幾類:
- 配置檔案目錄/etc/ansible/
- 執行檔案目錄/usr/bin
- Lib庫依賴目錄/usr/lib/pythonX.X/site-packages/ansible/
- Help文件目錄/usr/share/doc/ansible-X.X.X/
- Man文件目錄/usr/share/man/man1
整體的目錄概要可參考下圖所示的Ansible目錄樹結構
其中,如下目錄運維常要配置,需熟練掌握。
1)配置檔案目錄/etc/ansible,主要功能為:Inventory主機資訊配置、Ansible工具功能配置等。所有Ansible的配置均存放在該目錄下,運維日常的所有配置類操作也均基於此目錄進行。
2)執行檔案目錄/usr/bin,主要功能為:Ansible系列命令預設存放目錄。Ansible所有的可執行檔案均存放在該目錄下。
在/usr/lib/pythonXXX/site-packages/下,該目錄是系統當前預設的Python路徑,因為Ansible是基於Python編寫的,所以Ansible的所有lib庫檔案和模組檔案也均存放於該目錄下。
2.2 Ansible配置檔案解析
Inventory用於定義Ansible的主機列表配置,Ansible的自身配置檔案只有一個,即ansible.cfg,Ansible安裝好後它預設存放於/etc/ansible目錄下。ansible.cfg配置檔案可以存在於多個地方,Ansible讀取配置檔案的順序依次是當前命令執行目錄-->使用者家目錄下的.ansible.cfg-->/etc/ansible.cfg,先找到那個就使用哪個的配置。其ansible.cfg配置的所有內容均可在命令列通過引數的形式傳遞或定義在Playbooks中。
配置檔案ansible.cfg約有350多行語句,大多數為註釋預設配置項。該檔案遵循INI格式,分為如下幾類配置。
(1)[defaults]
該類配置下定義常規的連線類配置,如inventory、library、remote_tmp、local_tmp、forks、poll_interval、sudo_user、ask_sudo_pass、ask_pass、transport、remote_port等。
(2)[privilege_escalation]
處於安全形度考慮,部分公司不希望直接以root的高階管理員許可權直接部署應用,往往會開放普通使用者許可權並給予sudo的許可權,該部分配置主要針對sudo使用者提權的配置。
(3)[paramiko_connection]
定義paramiko_connection配置,該部分功能不常用,瞭解即可。
(4)[ssh_connection]
Ansible預設使用SSH協議連線對端主機,該部署是主要是SSH連線的一些配置,但配置項較少,多數預設即可。
(5)[accelerate]
Ansible連線加速相關配置。因為有部分使用者不滿意Ansible的執行速度,所以Ansible在連線和執行速度方面也在不斷地進行優化,該配置項在提升Ansible連線速度時會涉及,多數保持預設即可。
(6)[selinux]
關於selinux的相關配置幾乎不會涉及,保持預設配置即可。
(7)[colors]
Ansible對於輸出結果的顏色也進行了詳盡的定義且可配置,該選項對日常功能應用影響不大,幾乎不用修改,保持預設即可。
上面儘可能全地介紹了運維工作中可能需要修改的配置選項,除了在關閉首次連線提示(host_key_checking=False)或提速調整([accelerate]區域塊配置調整)時可能會稍作調整,其中絕大多數選項預設即可,Ansible安裝好後無需任何改動即可使用。
2.3 Ansible命令用法詳解
Ansible命令執行方式有Ad-Hoc、Ansible-playbook兩種方式。Ad-Hoc主要用於臨時命令的執行,Ansible-playbook可以理解為Ad-Hoc的集合,通過一定的規則編排在一起。
Ansible的通訊預設基於SSH,因此我們需要對主機先進行認證。Ansible認證方式有密碼認證和公私鑰兩種方式,其實完全等同於SSH的認證。Ansible預設使用公私鑰認證方式,究其原因無非是出於安全的考慮,密碼不用明文存放。以本機為例,執行如下命令即可新增本機認證資訊。
//ssh-keygen是Linux下認證金鑰生成、管理和轉換工具
ssh-keygen -N "" -b 4096 -t rsa -C "[email protected]" -f /root/.ssh/stanley.rsa
//為本機新增金鑰認證
ssh-copy-id -i /root/.ssh/stanley.rsa [email protected]
輸入正確的密碼資訊後結果認證,隨後在當前命令列輸入如下命令嘗試免密碼登入:
如不提示輸入密碼即可直接登入則表示金鑰驗證成功。
Ansible的命令使用格式如下:
ansible <host-pattern> [options]
<host-pattern>是Inventory中定義的主機或主機組,可以為Ip、hostname、Inventory中的group組名、具有"."或"*"或":"等特殊字元的匹配型字串,<>表示該選項是必須項,不可忽略。
[options]是Ansible的引數選項,[]表示該選項中的引數任選其一。
Ansible命令可用選項非常多,這裡列舉如下會用到的選項,詳細選項可參考man文件。
- -m NAME,--module-name=NAME:指定執行使用的模組
- -u USERNAME,--user=USERNAME:指定遠端主機以USERNAME執行命令。
- -s,--sudo:相當於Linux系統下的sudo命令
- -U SUDO_USERNAME,--sudo-user=SUDO_USERNAME:使用sudo,相當於Linux下的sudo命令。
具體示例如下:
//以bruce使用者執行ping存活檢測
ansible all -m ping -u bruce
//以bruce sudo至root執行ping存活檢測
ansible all -m ping -u bruce --sudo
//以bruce sudo至batman使用者執行ping存活檢測
ansible all -m ping -u bruce --sudo --sudo-user batman
但在新版本中Ansible的sudo命令廢棄,改為--become或-b,如上命令需改為如下:
//以bruce sudo至root執行ping存活檢測
ansible all -m ping -u bruce -b
//以bruce sudo至batman使用者執行ping存活檢測
ansible all -m ping -u bruce -b --become-user batman
Ansible-playbook的命令使用格式如下:
ansible-playbook playbook.yml
ansible-playbook命令後跟事先編輯好的playbook.yml檔案即可。Ansible-playbook新增的功能引數如下:
2.4 Ansible系列命令用法詳解與使用場景介紹
- ansible
- ansiblee-galaxy
- ansible-pull
- ansible-doc
- Ansible-playbook
- ansible-vault
- ansible-console
2.4.1 ansible
ansible命令主要在如下場景使用:
- 非固化需求
- 臨時一次性操作
- 二次開發介面呼叫
那麼什麼是非固化需求和臨時一次性操作呢?簡單來講,比如工作中我臨時想檢視web1伺服器組是否存活,或我臨時複製本地的/etc/fstab到web伺服器組的/tmp目錄下做測試,例如這些沒有規律的、臨時需要做的任務,我們稱之為非固化需求、臨時一次性操作。具體的命令使用如下:
//檢查伺服器存活
ansible web1 -m ping
//複製本地檔案到遠端
ansible web1 -m copy -a "src=/etc/fstab owner=root group=root mode=644 backup=yes"
Ansible的返回結果都非常友好,一般會用3種顏色來表示執行結果:紅色、綠色、橘黃色。其中紅色表示執行過程有異常,一般會終止剩餘所有的任務;綠色和橘黃色表示執行過程沒有異常,所有任務均正常執行,但橘黃色表示命令執行結束後目標有狀態的變化。
2.4.2 ansible-galaxy
ansible-galaxy的功能可以簡單地理解為GitHub或PIP的功能通過ansible-galaxy命令,我們可以根據下載量和關注量等資訊,查詢和安裝優秀的Roles。Roles是Ansible非常重要的一項功能。在ansible-galaxy上,我們可以上傳和下載Roles,這裡也是優秀Roles的聚集地,下載地址為https://galaxy.ansible.com
ansible-galaxy命令使用格式如下:
ansible-galaxy [init|info|install|list|remove] [--help] [options] ...
ansible-galaxy命令分三大部分:
(1)[init|info|install|remove]
- init:初始化本地的Roles配置,以備上傳Roles至galaxy。
- info:列表指定Role的詳細資訊
- install:下載並安裝galaxy指定的Roles到本地
- list:列出本地已下載的Roles
- remove:刪除本地已下載的Roles
Ansible2.0版本中,針對ansible-galaxy增加了login、import、delete、setup等功能,但這些功能需基於login在galaxy認證成功後方可執行,主要為了方便對galaxy上已有Roles的配置工作。
(2)help用法顯示[--help]
針對第一部分的inti、info等功能,其後跟--help可單獨顯示該項用法。例如:
ansible-galaxy init --help
執行後會返回ansible-galaxy init選項的用法說明。
Usage: ansible-galaxy init [options] role_name
Options:
--container-enabled Initialize the skeleton role with default contents for
a Container Enabled role.
-f, --force Force overwriting an existing role
-h, --help show this help message and exit
-c, --ignore-certs Ignore SSL certificate validation errors.
--init-path=INIT_PATH
The path in which the skeleton role will be created.
The default is the current working directory.
--offline Don't query the galaxy API when creating roles
--role-skeleton=ROLE_SKELETON
The path to a role skeleton that the new role should
be based upon.
-s API_SERVER, --server=API_SERVER
The API server destination
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--version show program's version number and exit
See 'ansible-galaxy <command> --help' for more information on a specific
command.
(3)引數項[options]
該部分結合第一部分的引數完成ansible-galaxy完整的功能用法,如:
ansible-galaxy inti [options] role_name 即ansible-galaxy init後 跟[-f|-h|-c|-p|--offline|-s SERVER|-v|--version]引數,後跟role-name成為一條完整的命令。
具體可參考如下:
//下載使用者hectcastro的Nginx這個Role到本地並忽略錯誤(預設存放在/etc/ansible/roles/)
ansible-galaxy --ignore-errors install azavea.git
因為ansible-galaxy是對https://galaxy.ansible.com網站的上傳、下載、配置類工作,如有類似如下報錯,請確保該網站可正常訪問。
the API server (galaxy.ansible.com) is not responding,please try again later.
2.4.3 ansible-pull
該指令的使用涉及Ansible的另一種工作模式:pull模式(Ansible預設使用push模式)。這和通常使用的push模式工作機理剛好相反,其適用與以下場景:1.你有數量巨大的機器需要配置,即使使用高併發執行緒依舊要花費很多時間;2你要在剛啟動的、沒有網路連線的主機上執行ansible。
ansible-pull命令使用格式如下:
ansible-pull [options] [playbook.yml]
通過ansible-pull結合git和crontab一併實現,其原理如下:通過crontab定期拉取指定的Git版本到本地,並以指定模式自動執行預先制定好的指令。
具體例項參考如下:
*/20 * * * * root /usr/local/bin/ansible-pull -o -C 2.1.0 -d /srv/www/kong-gw/ -i /etc/ansible/hosts -U git://git.kingifa.com/kong-gw-ansiblepull >> /var/log/ansible-pull.log 2>&1
2.4.4 ansible-doc
ansible-doc是Ansible模組文件說明,針對每個模組都有詳細的用法說明及應用案例介紹,功能和Linux系統man命令類似。該命令使用方式如下:
ansible-doc [options] [module...]
ansible-doc命令後跟[options]引數或[模組名],顯示模組用法說明,具體例項如下:
//列出支援的模組
ansible-doc -l
//模組功能說明
ansible-doc ping
2.4.5 ansible-playbook
ansible-playbook是日常應用中使用頻率最高的命令,其工作機制是:通過讀取預先編寫好的playbook檔案實現批量管理。要實現的功能與命令Ansible一樣,可以理解為按一定條件組成的ansible任務集。
ansible-playbook命令後跟YML格式的playbook檔案,執行事先編排好的任務集,命令使用方式如下:
ansible-playbook playbook.yml
具體示例如下:
//執行gw.yml這個playbook中定義的所有任務集
ansible-playbook gw.yml
2.4.6 ansible-vault
ansible-vault主要用於配置檔案加密,如編寫的Playbook配置檔案中包含敏感資訊,不希望其他人隨意檢視,ansible-vault可加密/解密這個配置檔案,具體使用方式如下:
Usage:ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] file_name
具體示例如下。
設定如下密碼,加密a.yml檔案
ansible-vault encrypt a.yml
會有以下輸入加密密碼提示:
Vault password:
Confirm Vault password:
Encryption successful
這時,再開啟a.yml檔案後會發現該檔案亂碼,只有通過如下命令解密後方可正常檢視。
ansible-vault decrypt a.yml
輸入預設的密碼後方可解密
Value password:
Decryption successful
此時a.yml檔案可正常檢視。
2.4.7 ansible-console
圖中的"[email protected](4)[f:5]$"是提示符,該提示符表示"當前的使用使用者@當前所在的Inventory中定義的組,預設是all分組(Inventory中all組所有主機的數量)[forks:執行緒數]$"。
使用cd命令可切換至指定Hosts或分組,同時提示符的相應資訊也會隨之變動,如下圖所示。
cd至webs分組後,原來的[email protected](4)[f:5]$也相應地變更為[email protected](3)[f:5],表示當前分組為webs分組,該分組所擁有的主機總數為3臺。執行forks 2後,提示符再次變更為[email protected](3)[f:2]$,表示設定併發的執行緒數為2。
所有的操作與Shell類似,而且支援Tab鍵補全,如啟動httpd服務時,鍵入service後連續按兩次Tab鍵後自動補全剩餘的命令選項。ansible-console命令用法如下圖所示。
如需啟動httpd服務,使用命令service name=httpd state=started,命令用法與Ad-Hoc一致,只是格式上的使用習慣不同而已。
使用完畢如希望退出,Ctrl+D或Ctrl+C即可退出當前的虛擬終端。
2.5 Ansible Inventory配置及詳解
Inventory是Ansible管理主機資訊的配置檔案,相當於系統HOSTS檔案的功能,預設存放在/etc/ansible/hosts。為方便批量管理主機,便捷使用其中的主機分組,Ansible通過Inventory來定義其主機和組,在使用時通過-i或--inventory-file指定讀取,與Ansible命令結合使用時組合如下:
ansible -i /etc/ansible/hosts webs -m ping
如果只有一個inventory時可不用指定路徑,預設讀取/etc/ansible/hosts。Inventory可以同時存在多個,而且支援動態生成,如AWS EC2、Cobbler等均支援。
2.5.1 定義主機和組
# Inventory可以直接為IP地址
192.168.37.149
# Inventory同樣支援Hostname的方式,後跟冒號加數字表示埠號,預設22號埠
ntp.magedu.com:2222
nfs.mageud.com
# 中括號內的內容表示一個分組的開始,緊隨其後的主機均屬於該組成員,空行後的主機亦屬於該組,即web2.magedu.com這臺主機也屬於[websevers]組
[websevers]
web1.magedu.com
web[10:20].magedu.com # [10:20]表示10-20z之間的所有數字(包括10和20),即表示web10.magedu.com,web11.magedu.com......web20.mageud.com的所有主機
web2.magedu.com[dbservers]
db-a.magedu.com
db-[b:f].magedu.com # [b:f]表示b到f之間的所有數字(包括b和f)
2.5.2 定義主機變數
[webservers]
web1.magedu.com http_port=808 maxRequestPerChild=801 # 自定義http_port的埠號為808,配置maxRequestPerChild為801
2.5.3 定義組變數
[groupservers]
web1.magedu.com
web2.magedu.com
[groupservers:vars]
ntp_server=ntp.magedu.com # 定義groupservers組中所有主機ntp_server值為ntp.magedu.com
nfs_server=nfs.magedu.com # 定義groupservers組中的所有主機nfs_server值為nfs.magedu.com
2.5.4 定義組巢狀及組變數
[apache]
httpd1.magedu.com
httpd2.magedu.com
[nginx]
ngx1.magedu.com
ngx2.magedu.com
[webservers:children]
apache
nginx
[webservers:vars]
ntp_server=ntp.magedu.com
2.5.5 多重變數定義
變數除了可以在Inventory中一併定義,也可以獨立於Inventory檔案之外單獨儲存到YAML格式的配置檔案中,這些檔案通常以.yml、.yaml、.json為字尾或者無後綴。
變數通常從如下4個位置檢索:
- Inventory配置檔案(預設/etc/ansible/hosts)
- Playbook中vars定義的區域
- Roles中vars目錄下的檔案
- Roles同級目錄group_vars和hosts_vars目錄下的檔案
假如foosball主機同屬於raleigh和webservers組,那麼其變數在如下檔案中設定均有效:
/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
2.5.6 其他Inventory引數列表
除了支援如上的功能外,ansible基於ssh連線Inventory中指定的遠端主機時,還內建了很多其他引數,用於指定其互動方式,如下列舉了部分重要引數:
ansible_ssh_host:指定連線主機
ansible_ssh_sort,指定ssh連線埠,預設22
ansible_ssh_user:指定ssh連線使用者
ansible_ssh_pass,指定ssh連線密碼
ansible_sudo_pass:指定ssh連線時sudo密碼
ansible_ssh_private_key_file:指定特有私鑰檔案
2.6 Ansible與正則
用法:
ansible <pattern_goes_here> -m <module_name> -a <arguments>
如下示例針對webservers進行正則匹配:
//重啟webservers組所有主機的httpd服務
ansible webservers -m service -a "name=httpd state=restarted"
(1)all(全量)匹配
匹配所有主機,all或*號功能相同。如檢測所有主機存活情況。
ansible all -m ping
ansible "*" -m ping
檢查192.168.1.0/24網段所有主機存活情況
ansible 192.168.1.* -m ping
(2)邏輯或(or)匹配
ansible "web1:web2" -m ping
(3)邏輯非(!)匹配
//所有在webservers組但不在phoenix組的主機
webservers:!phoenix
(4)邏輯與(&)匹配
//webservers組和staging組中同時存在的主機
webservers:&staging
(5)多條件組合
//webservers和dbservers兩個組中的所有主機在staging組中存在且在phoenix組中不存在的主機
webservers:dbservers:&staging:!phoenix
(6)模糊匹配
//所有以.magedu.com結尾的主機均符合
*.magedu.com
//one開頭.com結尾的所有主機和dbservers組中的所有主機
one*.com:dbservers
(7)域切割
[webservers]
cobweb
webbing
weber
webservers[0] # == cobweb
webservers[-1] # == weber
webservers[0:1] # == webservers[0],webservers[1],即 cobweb,webbing
(8)正則匹配
ansible同樣完整支援正則匹配功能,"~"開始表示正則匹配
~(web|db).*\.example\.com
檢測beta.example.com、web.example.com、green.example.com、beta.example.org、web.example.org、green.example.org的存活,使用如下匹配模式:
ansible "~(beta|web|green)\.example\.(com|org)" -m ping
檢測Inventory中所有以192.168.開頭的伺服器存活資訊:
ansible ~192\.168\.[0-9]\{\2}.[0-9]\{2,} -m ping