通過ansible自動化部署zabbix應用


zabbix在實際的應用中,可能需要監控的主機非常多,而每個主機的操作系統類型、版本也都不盡相同,在這種環境下,通過手動安裝zabbix的agent端已經不現實了,此時就需要借助自動化工具完成zabbix agent的安裝和配置。

要對海量主機進行zabbix agent的部署,難點有幾個方面,分別是:

1、要考慮每個主機的操作系統類型、版本
2、針對不同操作系統版本,需要安裝不同類型的zabbix agent客戶端版本
3、zabbix agent客戶端安裝完成后,還需要自動化的配置每個客戶端
4、zabbix agent配置文件中有些配置參數可能和每個主機有關(例如IP地址),此時就需要將主機信息寫入配置文件中,而每個主機的配置信息又各不相同。
5、每個主機上的配置文件自動配置后,最后還要啟動主機上的zabbix agent服務。

針對上面的5個問題,如何來實現批量自動化部署和配置呢,這里我們介紹一款自動化工具ansible,通過此工具,就可以實現zabbix agent的批量自動化部署。下面我們將介紹ansible的入門與使用,最后介紹通過ansible-playbook自動化一鍵部署zabbix agent的方法。

一、 ansible介紹與安裝使用
1.1、 ansible介紹與特點

ansible是一款自動化運維工具,基於Python開發,可以實現批量系統設置、批量程序部署、批量執行命令等功能。特點如下:

Ansible完全基於Python開發,要求python的版本為2.6以上。
Ansible豐富的內置模塊,近600個模塊完全滿足日常功能所需
Ansible默認通過SSH協議管理機器,因此,客戶端無需任何配置,管理端配置好后即可使用。
Ansible目前屬於Redhat公司,最新版本為Ansible2.7。

ansible的在企業中的應用環境主要有如下幾個方面:

應用代碼自動化部署
系統管理配置自動化
支持持續交付自動化
支持雲計算,大數據平台環境
批量任務執行可以寫成腳本,不用分發到遠程就可以執行
支持非root用戶管理操作,支持sudo
使用python編寫,維護更簡單。

1.2、 ansible的安裝

這里的安裝環境是centos7.5版本操作系統,首先需要安裝第三方epel源:

[root@ACA8D5EF ~]# yum install epel-release

Ansible依賴python環境,同時,Ansible已經是RHEL/Centos的一個組成部分,因此推薦通過yum安裝ansible:

[root@ACA8D5EF ~]# yum install ansible

1.3、 ansible的命令套件

安裝完ansible后,ansible一共提供了七個指令,分別是:ansible、ansible-doc、ansible-galaxy、ansible-lint、ansible-playbook、ansible-pull、ansible-vault 。

(1)、ansible

ansible是指令核心部分,其主要用於執行ad-hoc命令,即單條命令。默認后面需要跟主機和選項部分,默認不指定模塊時,使用的是command模塊。

(2)、ansible-doc

該指令用於查看模塊信息,常用參數有兩個-l 和 -s ,具體如下:
例如,列出所有已安裝的模塊:

# ansible-doc -l

查看具體某模塊的用法,這里如查看command模塊

# ansible-doc -s command

(3)、ansible-galaxy

ansible-galaxy 指令用於方便的從https://galaxy.ansible.com/ 站點下載第三方擴展模塊,可以形象的理解其類似於centos下的yum、python下的pip或easy_install 。

(4)、ansible-lint

ansible-lint是對playbook的語法進行檢查的一個工具。用法是ansible-lint playbook.yml 。

(5)、ansible-playbook

該指令是使用最多的指令,其通過讀取playbook 文件后,執行相應的動作,這個后面會做為一個重點來講。

(6)、ansible-pull

該指令使用需要談到ansible的另一種模式:pull 模式,這和平常經常用的push模式剛好相反,其適用於以下場景:
有數量巨大的機器需要配置,即使使用非常高的線程還是要花費很多時間
要在一個沒有網絡連接的機器上運行Anisble,比如在啟動之后安裝。

(7)、ansible-vault

ansible-vault主要應用於配置文件中含有敏感信息,又不希望被人看到,vault可以幫你加密/解密這個配置文件,屬高級用法。主要對於playbooks里比如涉及到配置密碼或其他變量時,可以通過該指令加密,這樣我們通過cat看到的是一個密碼串類的文件,編輯的時候需要輸入事先設定的密碼才能打開。這種playbook文件在執行時,需要加上 –ask-vault-pass參數,同樣需要輸入密碼后才能正常執行。

注:上面七個指令,用的最多的只有兩個ansible 和ansible-playbook ,這兩個一定要掌握,其它五個屬於拓展或高級部分。

二、 ansible架構與運行原理
2.1、 ansible基本架構

下圖是ansible的基本架構:

下面介紹下每個組成部分的含義:

核心:ansible

核心模塊(Core Modules):是ansible自帶的模塊,Ansible模塊資源分發到遠程節點使其執行特定任務或匹配一個特定的狀態。

擴展模塊(Custom Modules):如果核心模塊不足以完成某種功能,可以添加擴展模塊。

插件(Plugins):完成較小型的任務。輔助模塊來完成某個功能。

劇本(Playbooks):ansible的任務配置文件,將多個任務定義在劇本中,由ansible自動執行。例如安裝一個nginx服務,那么我們可以把這拆分為幾個任務放到一個playbook中。例如:第一步需要下載nginx的安裝包。第二步我可能考慮需要做的就是將我事先寫好的nginx.conf的配置文件下發的目標服務器上。第三步,我們需要把服務啟動起來。第四步,我們可能需要檢查端口是否正常開啟。那么這些步驟可以通過playbook來進行整合,然后通過inventory來下發到想要執行劇本的主機上。

連接插件(Connectior Plugins):ansible基於連接插件連接到各個主機上,默認是基於SSH連接到目標機器上執行操作的,但是它還支持其他的連接方法,所以需要有連接插件,管理端支持local 、ssh、 paramiko三種方式連接被管理端。

主機清單(Host Inventory):定義ansible管理主機的策略,一般小型環境下只需要在host文件中寫入主機的IP地址即可,但是到了中大型環境就需要使用靜態inventory或者動態主機清單來生所需要執行的目標主機。

2.2、 ansible任務執行模式

ansible執行自動化任務,分為兩種執行模式:

1、ad-hoc:單個模塊,單條命令的批量執行,稱之為ad-hoc
2、playbook:這個可以理解成為面向對象的編程,就像上面舉例那樣可以把多個想要執行的任務放到一個playbook中,當然多個任務在事物邏輯上最好是有上下聯系的。通過多個任務可以完成一個總體的目標,這就是playbook。

三、 ansible主機和組的配置
3.1、簡單的主機和組

ansible的配置文件位於/etc/ansible目錄下,主要有ansible.cfg、hosts文件。本節重點介紹主機與組定義文件/etc/ansible/hosts.

/etc/ansible/hosts最簡單的格式如下:

www.ixdba.net [webservers] ixdba1.net ixdba2.net [dbservers] db.ixdba1.net db.ixdba2.net

中括號中的名字代表組名,可以根據需求將龐大的主機分成具有標識的組,如上面分了兩個組webservers和dbservers組;

主機(hosts)部分可以使用域名、主機名、IP地址表示;當然使用前兩者時,也需要主機能反解析到相應的IP地址,一般此類配置中多使用IP地址;

未分組的機器需保留在hosts的頂部。

3.2、指定主機范圍

可在/etc/ansible/hosts文件中,指定主機的范圍,示例如下:

[web] www[01:50].ixdba.net [db] db[a:f].ixdba.net

3.3、主機變量

以下是Hosts部分中經常用到的變量部分:

ansible_ssh_host #用於指定被管理的主機的真實IP
ansible_ssh_port #用於指定連接到被管理主機的ssh端口號,默認是22
ansible_ssh_user #ssh連接時默認使用的用戶名
ansible_ssh_pass #ssh連接時的密碼
ansible_sudo_pass #使用sudo連接用戶時的密碼
ansible_sudo_exec #如果sudo命令不在默認路徑,需要指定sudo命令路徑
ansible_ssh_private_key_file #秘鑰文件路徑,秘鑰文件如果不想使用ssh-agent管理時可以使用此選項
ansible_shell_type #目標系統的shell的類型,默認sh
ansible_connection #SSH 連接的類型:local , ssh , paramiko,在 ansible1.2之前默認是 paramiko ,后來智能選擇,優先使用基於ControlPersist 的ssh
ansible_pythoninterpreter #用來指定python解釋器的路徑,默認為/usr/bin/python 同樣可以指定ruby 、perl的路徑
ansible_interpreter #其他解釋器路徑,用法與ansible_python_interpreter類似,這里””可以是ruby或perl等其它語言

例子1:

[web]
    192.168.78.11 http_port=80
    192.168.78.12 http_port=80

還可以改成這樣:

[web]
    192.168.78.11
    192.168.78.12
[web:vars]
    http_port=80

例子2:

[webhost] host1 host2 [dbhost] host2 host3 [allhosts:children] webhost Dbhost

主機組可以包含主機組,主機的變量可以通過繼承關系,繼承到最高等級的組的變量。定義主機組之間的繼承關系我們使用”:children”來表示.

四、 ansible.cfg與默認配置
/etc/ansible/ansible.cfg文件中定義了ansible的主機的默認配置部分,如默認是否需要輸入密碼、是否開啟sudo認證、action_plugins插件的位置、hosts主機組的位置、是否開啟log功能、默認端口、key文件位置等等。

#inventory = /etc/ansible/hosts 該參數表示資源清單inventory文件的位置,資源清單就是一些Ansible需要連接管理的主機列表

#library = /usr/share/my_modules/ Ansible的操作動作,無論是本地或遠程,都使用一小段代碼來執行,這小段代碼稱為模塊,這個library參數就是指向存放Ansible模塊的目錄

#module_utils = /usr/share/my_module_utils/

#remote_tmp = ~/.ansible/tmp 指定遠程執行的路徑

#local_tmp = ~/.ansible/tmp ansible管理節點的執行路徑

#forks = 5 forks 設置默認情況下Ansible最多能有多少個進程同時工作,默認設置最多5個進程並行處理。具體需要設置多少個,可以根據控制主機的性能和被管理節點的數量來確定。

#poll_interval = 15 輪詢間隔

#sudo_user = root sudo使用的默認用戶 ,默認是root

#ask_sudo_pass = True 是否需要用戶輸入sudo密碼

#ask_pass = True 是否需要用戶輸入連接密碼

#remote_port = 22 這是指定連接對端節點的管理端口,默認是22,除非設置了特殊的SSH端口,不然這個參數一般是不需要修改的

#module_lang = C 這是默認模塊和系統之間通信的計算機語言,默認為’C’語言.
host_key_checking = False 跳過ssh首次連接提示驗證部分,False表示跳過。

#timeout = 10 連接超時時間

#module_name = command 指定ansible默認的執行模塊

#nocolor = 1 默認ansible會為輸出結果加上顏色,用來更好的區分狀態信息和失敗信息.如果你想關閉這一功能,可以把’nocolor’設置為‘1’:

#private_key_file=/path/to/file.pem 在使用ssh公鑰私鑰登錄系統時候,使用的密鑰路徑。

五、 Ad-hoc與commands模塊
5.1、Ad-Hoc 執行格式

Ad-Hoc 是指ansible下臨時執行的一條命令,並且不需要保存的命令,對於復雜的命令后面會講用playbook。講到Ad-hoc 就要提到模塊,所有的命令執行都要依賴於事先寫好的模塊,默認安裝好的ansible里面已經自帶了很多模塊,如:command、raw、shell、file、cron等,具體可以通過ansible-doc -l 進行查看 。

ansible命令的常用選項:

-m MODULE_NAME:指定要執行的模塊的名稱,如果不指定-m選項,默認是COMMAND模塊。
-a MODULE_ARGS,:指定執行模塊對應的參數選項。
-k:提示輸入SSH登錄的密碼而不是基於密鑰的驗證
-K:用於輸入執行su或sudo操作時需要的認證密碼。
-b:表示提升權限操作。
–become-method:指定提升權限的方法,常用的有 sudo和su,默認是sudo。
–become-user:指定執行 sudo或su命令時要切換到哪個用戶下,默認是root用戶。
-B SECONDS:后台運行超時時間
-C:測試一下會改變什么內容,不會真正去執行,主要用來測試一些可能發生的變化
-f FORKS,:設置ansible並行的任務數。默認值是5
-i INVENTORY: 指定主機清單文件的路徑,默認為/etc/ansible/hosts。

一個ad-hoc命令的執行,需要按以下格式進行執行:

ansible 主機或組   -m  模塊名  -a '模塊參數' ansible參數

主機和組:是在/etc/ansible/hosts 里進行指定的部分,當然動態Inventory使用的是腳本從外部應用里獲取的主機。

模塊名:可以通過ansible-doc -l 查看目前安裝的模塊,默認不指定時,使用的是command模塊,具體可以查看/etc/ansible/ansible.cfg 的“#module_name = command ” 部分,默認模塊可以在該配置文件中進行修改;

模塊參數:可以通過 “ansible-doc 模塊名” 查看具體的用法及后面的參數;

ansible參數:可以通過ansible命令的幫忙信息里查看到,這里有很多參數可以供選擇,如是否需要輸入密碼、是否sudo等。

5.2、commands模塊

command模塊包含如下選項:

creates:一個文件名,當該文件存在,則該命令不執行,反正,則執行。
free_form:要執行的linux指令
chdir:在執行指令之前,先切換到該指定的目錄
removes:一個文件名,當該文件存在時,則該選項執行,反之,不執行。

注意:commands模塊的執行,在遠程主機上,需要有python環境的支持。

該模塊通過-a跟上要執行的命令可以直接執行,不過命令里如果有帶有特殊字符( “<“, “>”, “|”, “&”等)那么則執行不成功。

5.3、shell 模塊

在遠程節點上執行命令,用法和command一樣,不過shell模塊執行命令的時候使用的是/bin/sh,所以shell模塊可以執行任何命令。

ansible 172.16.213.233 -m shell -a 'ps -ef|grep sshd' ansible 172.16.213.233 -m shell -a 'sh /tmp/install.sh >/tmp/install.log'

上面這個命令是執行遠程機器上的腳本,腳本路徑為/tmp/install.sh(遠程主機上的腳本,非本機的),然后將執行命令的結果存放在遠程主機路徑/tmp/install.log中,注意在進行保存文件的時候,寫上全路徑,否則就會保存在登錄之后的默認路徑中。

官方上說,command用起來更安全,更有可預知性。

5.4、raw模塊

raw模塊功能類似與前面說的command、shell能夠完成的操作,raw也都能完成。不同的是,raw模塊不需要遠程主機上的python環境。

ansible要執行自動化操作,需要管理機上裝ansible,客戶機上也需要安裝python,如果客戶機上沒有安裝python模塊,那么command、shell模塊將無法工作,而raw卻可以正常工作,因此,如果有的機器是沒有裝python,或者說安裝的python版本在python2.4以下,就可以使用raw模塊來裝python、python-simplejson等。

如果有些機器壓根就裝不了python的話(比如交換機,路由器等),那么,直接用raw模塊是最好的選擇。

舉例:

ansible 172.16.213.233 -m raw -a “ps -ef|grep sshd|awk ‘{print \$2}’ ” ansible 172.16.213.107 -m raw -a "yum -y install python26" -k

raw模塊和comand、shell模塊不同的還有:raw沒有chdir、creates、removes參數

[root@localhost ansible]# ansible 172.16.213.157 -m command -a 'chdir=/tmp touch test1.txt' -k [root@localhost ansible]# ansible 172.16.213.157 -m shell -a 'chdir=/tmp touch test2.txt' -k [root@localhost ansible]# ansible 172.16.213.157 -m raw -a 'chdir=/tmp touch test3.txt' -k

5.5、script模塊

script模塊是將管理端的shell腳本拷貝到被管理的遠程主機上執行,其原理是先將shell復制到遠程主機,再在遠程主機上執行,此模塊的執行,也不需要遠程主機上的python環境。

ansible 172.16.213.233 -m script -a 'sh /tmp/install1.sh >/tmp/install.log'

腳本/tmp/install1.sh在管理端本機上,script 模塊執行的時候將腳本傳送到遠程的172.16.213.233主機中,然后執行這個腳本,同時,將執行的輸出日志文件保存在遠程主機對應的路徑/tmp/install.log下,這里保存日志文件的時候,最好用全路徑。

六、 ansible其它常用功能模塊
6.1、ping模塊

測試主機是否是通的,用法很簡單,不涉及參數:

[root@361way ~]# ansible 172.16.213.170 -m ping 172.16.213.170 | SUCCESS => { "changed": false, "ping": "pong" }

6.2、file模塊

file模塊主要用於遠程主機上的文件操作,file模塊包含如下選項:

force:需要在兩種情況下強制創建軟鏈接,一種是源文件不存在但之后會建立的情況下;另一種是目標軟鏈接已存在,需要先取消之前的軟鏈,然后創建新的軟鏈,有兩個選項:yes|no
group:定義文件/目錄的屬組
mode:定義文件/目錄的權限
owner:定義文件/目錄的屬主
path:必選項,定義文件/目錄的路徑
recurse:遞歸的設置文件的屬性,只對目錄有效
src:要被鏈接的源文件的路徑,只應用於state=link的情況
dest:被鏈接到的目標路徑,只應用於state=link的情況
state: 有如下幾個選項:
directory:表示目錄,如果目錄不存在,則創建目錄。
link:創建軟鏈接
hard:創建硬鏈接
touch:如果文件不存在,則會創建一個新的文件,如果文件或目錄已存在,則更新其最后修改時間
absent:刪除目錄、文件或者取消鏈接文件。

使用示例:

ansible 172.16.213.233 -m file -a "path=/mnt/abc123 state=directory" ansible 172.16.213.233 -m file -a "path=/mnt/abc123 owner=nobody group=nobody mode=0644 recurse=yes" ansible 172.16.213.233 -m file -a "path=/mnt/syncfile.txt owner=sshd group=sshd mode=0644" ansible 172.16.213.233 -m file -a "path=/mnt/syncfile.txt mode=0444" ansible 172.16.213.233 -m file -a "src=/etc/ssh/sshd_config dest=/mnt/sshd_config owner=sshd state=link" ansible 172.16.213.233 -m file -a "path=/tmp/backup.tar.gz state=absent" ansible 172.16.213.233 -m file -a "path=/tmp/ansibletemp state=touch"

6.3、copy模塊

Copy模塊用於復制文件到遠程主機,copy模塊包含如下選項:

backup:在覆蓋之前將原文件備份,備份文件包含時間信息。有兩個選項:yes|no
content:用於替代”src”,可以直接設定指定文件的值
dest:必選項。要將源文件復制到的遠程主機的絕對路徑,如果源文件是一個目錄,那么該路徑也必須是個目錄
directory_mode:遞歸的設定目錄的權限,默認為系統默認權限
force:如果目標主機包含該文件,但內容不同,如果設置為yes,則強制覆蓋,如果為no,則只有當目標主機的目標位置不存在該文件時,才復制。默認為yes
others:所有的file模塊里的選項都可以在這里使用
src:要復制到遠程主機的文件在本地的地址,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞歸復制。在這種情況下,如果路徑使用”/”來結尾,則只復制目錄里的內容,如果沒有使用”/”來結尾,則包含目錄在內的整個內容全部復制,類似於rsync。

copy模塊舉例:

ansible 172.16.213.233 -m copy -a 'src=/etc/sudoers dest=/app/sudoers owner=root group=root mode=440 backup=yes' ansible 172.16.213.233 -m copy -a "src=/etc/sudoers dest=/app/sudoers validate='visudo -cf %s'" ansible 172.16.213.233 -m copy -a 'src=/etc/yum dest=/app/ owner=root group=root directory_mode=644' ansible 172.16.213.233 -m copy -a 'src=/etc/yum/ dest=/app/bak owner=root group=root directory_mode=644'

6.4、service模塊

用於管理遠程主機上的服務,該模塊包含如下選項:

enabled:是否開機啟動 yes|no
name:必選項,服務名稱
pattern:定義一個模式,如果通過status指令來查看服務的狀態時,沒有響應,就會通過ps指令在進程中根據該模式進行查找,如果匹配到,則認為該服務依然在運行
sleep:如果執行了restarted,在則stop和start之間沉睡幾秒鍾
state:對當前服務執行啟動,停止、重啟、重新加載等操作(started,stopped,restarted,reloaded)

使用示例:

ansible 172.16.213.233 -m service -a "name=httpd state=started" ansible 172.16.213.233 -m service -a "name=httpd enabled=yes"

6.5、cron模塊

用於管理計划任務,包含如下選項:

backup:對遠程主機上的原任務計划內容修改之前做備份
cron_file:用來指定一個計划任務文件,也就是將計划任務寫到遠程主機上/etc/cron.d目錄下,創建一個文件對應的計划任務。
day:日(1-31,,/2,……)
hour:小時(0-23,,/2,……)
minute:分鍾(0-59,,/2,……)
month:月(1-12,,/2,……)
weekday:周(0-7,*,……)
job:要執行的任務,依賴於state=present
name:定義定時任務的描述信息
special_time: 特殊的時間范圍,參數:reboot(重啟時),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小時)
state:確認該任務計划是創建還是刪除,有兩個值可選,分別是present和absent,present表示創建定時任務,absent表示刪除定時任務,默認為present。
user:以哪個用戶的身份執行job指定的任務。

使用示例:

ansible 172.16.213.233 -m cron -a 'name="job for reboot" special_time=reboot job="/data/bootservice.sh"' ansible 172.16.213.233 -m cron -a 'name="yum autoupdate" weekday="6" minute=20 hour=1 user="root" job="yum -y update"' ansible 172.16.213.233 -m cron -a 'backup="True" name="autobackup" weekday="6" minute=30 hour=1 user="root" job="/home/ixdba/backup.sh"' ansible 172.16.213.233 -m cron -a 'name="checkhttp" minute=30 hour=12 user="root" job="/home/ixdba/check_http.sh" cron_file="check_http_for_ansible" ' ansible 172.16.213.233 -m cron -a 'name="yum autoupdate" state=absent'

6.6、yum模塊

使用yum包管理器來管理軟件包,其選項有:

config_file:yum的配置文件
disable_gpg_check:關閉gpg_check
disablerepo:不啟用某個源
enablerepo:啟用某個源
name:要進行操作的軟件包的名字,也可以傳遞一個url或者一個本地的rpm包的路徑
state:表示要安裝還是刪除軟件包,要安裝軟件包,可選擇present(安裝)、installed(安裝)、 latest(安裝最新版本),刪除軟件包可選擇absent、removed。

示例如下:

ansible 172.16.213.77 -m yum -a "name=redis state=installed" ansible 172.16.213.77 -m yum -a "name=redis state=removed" ansible 172.16.213.77 -m yum -a "name=redis state=latest enablerepo=epel" ansible 172.16.213.77 -m yum -a " name=http://mirrors.aliyun.com/centos/7.4.1708/os/x86_64/Packages/bash-4.2.46-28.el7.x86_64.rpm state=present "

6.7、user模塊與group模塊

user模塊是請求的是useradd, userdel, usermod三個指令,goup模塊請求的是groupadd, groupdel, groupmod 三個指令。

name # 指定用戶名
group # 指定用戶的主組
groups # 指定附加組,如果指定為(‘groups=’)表示刪除所有組。
shell # 指定默認shell
state #設置帳號狀態,不指定為默認為present,表示創建,指定值為absent表示刪除
remove #當使用狀態為state=absent時使用,類似於userdel –remove選項。

示例:

ansible 172.16.213.77 -m user -a "name=testuser1" ansible 172.16.213.77 -m user -a "name=testuser2 groups=admins,developers" //添加用戶時,同時添加附組 ansible 172.16.213.77 -m user -a "name=testuser3 state=absent remove=yes" //刪除用戶的同時 ,刪除用記家目錄

批量修改用戶密碼:

echo "123456" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) -stdin $1$yjJ74Wid$x0QUaaHzA8EwWU2kG6SRB1 ansible 172.16.213.77 -m user -a 'name=testuser1 password="$1$Kklap7y3$3AYJdqrcmZUMt9W2/MYE4." '

-1:表示采用的是MD5加密算法。
-salt:指定salt值。在使用加密算法進行加密時,即使密碼一樣,salt不一樣,所計算出來的hash值也不一樣,除非密碼一樣,salt值也一樣,計算出來的hash值才一樣。
“< /dev/urandom tr -dc ‘[:alnum:]’ | head -c 32“產生一個隨機的salt。

passwd的值不能是明文,passwd關鍵字后面應該是密文,且密文將被保存在/etc/shadow文件中。

6.8、synchronize模塊

此模塊通過調用rsync進行文件或目錄同步。

archive:歸檔,相當於同時開啟recursive(遞歸),links,perms,itmes,owner,group,-D選項都為yes,默認該選項為開啟
checksum:跳過檢測sum值,默認關閉
compress:是不開啟壓縮,默認開啟
copy_links:復制鏈接文件,默認為no,注意后面還有一個links參數
delete:刪除不存在的文件,默認為no
dest:目錄路徑
dest_prot:默認為22,ssh協議
mode:push和pull模塊,push模塊的話,一般用於從本機向遠程主機上傳文件,pull模式用於從遠程主機上拉取文件

示例:

ansible 172.16.213.77 -m synchronize -a 'src=/mnt/a dest=/tmp' ansible 172.16.213.77 -m synchronize -a 'mode=pull src=/mnt/a dest=/tmp'

6.9、setup模塊

setup模塊,主要用於獲取主機信息,在playbooks里經常會用到的一個參數gather_facts就與該模塊相關。setup模塊下經常使用的一個參數是filter參數,具體使用示例如下(由於輸出結果較多,這里只列命令不寫結果):

[root@linux ~]# ansible 172.16.213.77 -m setup -a 'filter=ansible_*_mb' 表示查看主機內存信息
[root@linux ~]# ansible 172.16.213.77 -m setup -a 'filter=ansible_em[1-2]' 表示查看地接口為em1-2的網卡信息
[root@linux ~]# ansible all -m setup --tree /tmp/facts 表示將所有主機的信息輸入到/tmp/facts目錄下,每台主機的信息輸入到主機名文件中(/etc/ansible/hosts里的主機名)

6.10、get_url模塊

該模塊主要用於從http、ftp、https服務器上下載文件(類似於wget),主要有如下選項:

sha256sum:下載完成后進行sha256 check;
timeout:下載超時時間,默認10s
url:下載的URL
url_password、url_username:主要用於需要用戶名密碼進行驗證的情況
use_proxy:表示使用代理,代理需事先在環境變更中定義

示例:

ansible 172.16.213.77 -m get_url -a "url=http://172.16.213.157/Python-2.7.14.tgz dest=/mnt/python-2.7.14.tgz"

七、 ansible-playbook的使用
7.1、playbook簡介

playbook字面意思,即劇本,現實中由演員按照劇本表演,在Ansible中,這次由計算機進行表演,由計算機安裝,部署應用,提供對外服務,以及組織計算機處理各種各樣的事情。

那么為什么要使用playbook呢?

執行一些簡單的任務,使用ad-hoc命令可以方便的解決問題,但是有時一個設施過於復雜,需要大量的操作時候,執行的ad-hoc命令是不適合的,這時最好使用playbook,就像執行shell命令與寫shell腳本一樣,也可以理解為批處理任務,不過playbook有自己的語法格式。

7.2、playbook文件的格式

playbook文件由YAML語言編寫。 YAML是一個類似 XML、JSON的標記性語言,YAML強調以數據為中心,並不是以標識語言為重點。因而YAML本身的定義比較簡單,號稱“一種人性化的數據格式語言”。首先學習了解一下YAML的格式,對后面書寫playbook很有幫助。

以下為playbook常用到的YAML格式規范。

大小寫敏感
使用空格作為嵌套縮進工具,縮進時不允許使用Tab鍵
縮進的空格數目不重要,只要相同層級的元素左側對齊即可
使用“-”(橫線) + 單個空格:表示單個列表項
使用 “:”(冒號) + 空格:表示單個鍵值對
使用”{}”表示一個鍵值表
文件的第一行應該以 ”—” (三個連字符)開始,表明YMAL文件的開始。
在同一行中,#之后的內容表示注釋,類似於shell,python和ruby。
YMAL中的列表元素以”-”開頭然后緊跟着一個空格,后面為元素內容。
同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
play中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以”:”分隔表示,”:”后面還要增加一個空格。

下面是yaml文件的格式:

--- # 文檔開始
- 第一章 簡介 - 第二章 設計目錄 # 客戶訂單 date: 2018-09-30 customer:  - name: Jai items: - no: 1234 #訂單號 - descript: cpu

下面是Playbook文件格式例子:

- apple - banana - Orange service: name=httpd state=restarted

等價於JSON的這種格式:

[
 “apple”,
 “banana”,
 “orange”
]

playbook文件是通過ansible-playbook命令進行解析的,ansbile-playbook命令會根據自上而下的順序依次執行playbook文件中的內容。同時,playbook開創了很多特性,它可以允許傳輸某個命令的狀態到后面的指令,它也可以從一台機器的文件中抓取內容並附為變量,然后在另一台機器中使用,這使得playbook可以實現一些復雜的部署機制,這是ansible命令無法實現的。

7.3、playbook的構成

playbook是由一個或多個“play”組成的列表。play的主要功能在於,將事先合並為一組的主機裝扮成事先通過ansible定義好的角色。將多個play組織在一個playbook中就可以讓它們聯同起來按事先編排的機制完成一系列復雜的任務。

其主要有以下四部分構成

target部分: 定義將要執行 playbook 的遠程主機組
variable部分: 定義playbook運行時需要使用的變量
task部分: 定義將要在遠程主機上執行的任務列表
handler部分: 定義task 執行完成以后需要調用的任務

而其對應的目錄層為五個(視情況可變化),分別為:

vars 變量層
tasks 任務層
handlers 觸發條件
files 文件
template 模板

7.4、playbook的語法詳解

(1)、Hosts和Users

playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶身份執行任務。

hosts:用於指定要執行指定任務的主機,每個playbook都必須指定hosts,hosts也可以使用通配符格式。主機或主機組在inventory清單中指定,可以使用系統默認的/etc/ansible/hosts,也可以自己編輯,在運行的時候加上-i選項,可指定自定義主機清單的位置。在運行清單文件的時候,–list-hosts選項會顯示那些主機將會參與執行任務的過程中。

remote_user:用於指定在遠程主機上執行任務的用戶。可以指定任意用戶,也可以使用sudo,但是用戶必須要有執行相應任務的權限。

(2)、任務列表(tasks list)

play的主體部分是task list。

task list中的各任務按次序逐個在hosts中指定的所有主機上執行,即在所有主機上完成第一個任務后再開始第二個。在運行自上而下某playbook時,如果中途發生錯誤,則所有已執行任務都將回滾,因此在更正playbook后需要重新執行一次。

task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量。模塊執行是冪等的(冪等性; 即一個命令,即使執行一次或多次, 其結果也一樣),這意味着多次執行是安全的,因為其結果均一致。tasks包含name和要執行的模塊,name是可選的,只是為了便於用戶閱讀,建議加上去,模塊是必須的,同時也要給予模塊相應的參數。

定義tasks推薦使用module: options”的格式,例如:
service: name=httpd state=running

(3)、handlers

用於當關注的資源發生變化時采取一定的操作。handlers是和“notify”配合使用的。

“notify”這個動作可用於在每個play的最后被觸發,這樣可以避免多次有改變發生時,每次都執行指定的操作,通過“notify”,僅在所有的變化發生完成后一次性地執行指定操作。
在notify中列出的操作稱為handler,也就是說notify用來調用handler中定義的操作。

注意:在 notify中定義的內容一定要和handlers中定義的“ - name”內容一樣,這樣才能達到觸發的效果,否則會不生效。

(4)、tags

tags用於讓用戶選擇運行或略過playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分;但是當一個playbook任務比較多時,一個一個的判斷每個部分是否發生了變化,也需要很長時間。因此,如果確定某些部分沒有發生變化,就可以通過tags跳過這些代碼片斷。

7.5、Playbook執行結果解析

使用ansible-playbook運行playbook文件,輸出的內容為JSON格式。並且由不同顏色組成,便於識別。一般而言,輸出內容中:

綠色代表執行成功,但系統保持原樣
黃色代表系統狀態發生改變,也就是執行的操作生效
紅色代表執行失敗,會顯示錯誤信息。

一個簡單的playbook文件:

- name: create user hosts: 172.16.213.233 user: root gather_facts: false vars: - user1: "testuser" tasks: - name: start createuser user: name="{{ user1 }}"

上面的playbook 實現的功能是新增一個用戶:

name參數對該playbook實現的功能做一個概述,后面執行過程中,會輸出name的值;
hosts參數指定了對哪些主機進行操作。
user參數指定了使用什么用戶登錄到遠程主機進行操作。
gather_facts參數指定了在下面任務執行前,是否先執行setup模塊獲取主機相關信息,這在后面的task會使用到setup獲取的信息時需要用到。
vars參數,指定了變量,這里指字一個user1變量,其值為testuser,需要注意的是,變量值一定要用引號括起來。
tasks指定了一個任務,其下面的name參數同樣是對任務的描述,在執行過程中會打印出來。user是一個模塊,user后面的name是user模塊里的一個參數,而增加的用戶名字調用了上面user1變量的值。

7.6、收集facts信息

facts組件是Ansible用於采集被管理機器設備信息的一個功能。可以使用setup模塊查機器的所有facts信息,facts信息包括遠端主機發行版,IP地址,CPU核數,系統架構,主機名等等,可以使用filter來查看指定信息。整個facts信息被包裝在一個json格式的數據結構中。

[root@ansible playbook]# ansible 172.16.213.233 -m setup

所有數據格式都是JSON格式,facts還支持查看指定信息,如下所示:

[root@ansible playbook]# ansible 172.16.213.233 -m setup -a 'filter=ansible_all_ipv4_addresses'

playbook在執行的時候,默認的第一個tasks就是收集遠端被管主機的facts信息,如果后面的task不會使用到setup獲取的信息時,可以禁止ansible收集facts,在playbook中的hosts指令下面設置“gather_facts: false”即可。默認gather_facts的值為true。

facts經常被用在條件語句和模板當中,也可以用於根據指定的標准創建動態主機組。

7.7、通過playbook自動化部署zabbix agent應用案例

下面是通過playbook自動化部署zabbix agent的一個yaml文件,內容如下:

- hosts: dlab
  remote_user: root
  gather_facts: yes
  vars:
     IPDD: "{{ ansible_default_ipv4['address'] }}" tasks: - name: update bash in cetnos 7 version yum: name=https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.0-2.el7.x86_64.rpm state=present when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == "7" - name: update bash in cetnos 6 version yum: name=https://repo.zabbix.com/zabbix/4.0/rhel/6/x86_64/zabbix-agent-4.0.1-1.el6.x86_64.rpm state=present when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == "6" - name: Cofiguration zabbix-agent copy: src=/app/zabbix_agentd.conf dest=/etc/zabbix/zabbix_agentd.conf tags: zabbix_agentd.conf - name: modif zabbix-agent.conf lineinfile: dest=/etc/zabbix/zabbix_agentd.conf regexp=^Hostname=myip line=Hostname={{ IPDD }} tags: zabbix_agentd.conf - name: Start zabbix-agent service: name=zabbix-agent state=started enabled=yes tags: start zabbix-agent

這個playbook首先定義了一個主機組dlab,然后開啟了gather_facts,接着,定義了一個變量IPDD,然后開始執行任務,第一個任務根據操作系統版本不同,安裝不同的zabbix-agent,這里只涉及到了centos6.x和7.x版本,然后,將本地/app/zabbix_agentd.conf文件拷貝到遠程dlab主機組,這是配置zabbix-agent,接下來,開始修改zabbix_agentd.conf文件中的內容,這里用到了lineinfile模塊,這是個文件操作模塊,它可以使用一個正則表達式替換、刪除一個現有的行。最后一個任務是啟動zabbix-agent服務。

好啦,自動化部署zabbix-agent,通過ansible就可以很輕松愉快的搞定了,而主機在部署zabbix以后,zabbix中可以通過開啟自動發現功能,讓zabbix web自動發現部署的主機,然后自動加入到zabbix web監控中,這樣,從部署到主機接入zabbix web監控都是自動完成了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM