標籤:

[DevOps]Ansible自動化運維入門到實戰(下)

[DevOps]Ansible自動化運維入門到實戰(下)

版權申明:本人僅授權實驗樓發布、轉載、下載及傳播。

4.3 Ansible常用模塊

  1. setup 獲取主機信息,playbook中的gather_facts選項即為收集主機信息,自動化運維繫統開發中的資產信息管理即可使用此模塊實現

  2. 示例一:獲取主機的CPU型號

bash shiyanlou@ubunt:~$ ansible all -m setup -a filter=ansible_processor 192.168.1.1 | SUCCESS => { "ansible_facts": { "ansible_processor": [ "0", "GenuineIntel", "Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz", "1", "GenuineIntel", "Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz", "2", "GenuineIntel", "Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz", "3", "GenuineIntel", "Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz" ] }, "changed": false, "failed": false } shiyanlou@ubunt:~$

  • 示例二:獲取主機信息並保存至/tmp目錄,文件名為主機的IP地址

bash shiyanlou@ubunt:~$ ansible all -m setup --tree /tmp

進入/tmp目錄查看文件192.168.1.1,其中包含所有主機信息

bash shiyanlou@ubunt:~$ cd /tmp shiyanlou@ubunt:/tmp$ ls -al total 84 drwxrwxrwt 13 root root 4096 Aug 28 15:04 . drwxr-xr-x 24 root root 4096 Aug 28 09:43 .. -rw-rw-r-- 1 shiyanlou shiyanlou 24892 Aug 28 15:04 192.168.1.1 ...... shiyanlou@ubunt:/tmp$

  1. copy 複製文件到遠程主機

複製文件 /home/shiyanlou/shiyanlou.tar.gz至目標主機/tmp目錄下,並設置文件所有者和所屬組為shiyanlou,文件許可權為-rw-r--r--

bash shiyanlou@ubunt:~$ ansible all -m copy -a "src=/home/shiyanlou/shiyanlou.tar.gz dest=/tmp owner=shiyanlou group=shiyanlou mode=0644" 192.168.1.1 | SUCCESS => { "changed": true, "checksum": "2055f455cf90fd1e43c6b0af956a50fdf6dc1112", "dest": "/tmp/shiyanlou.tar.gz", "failed": false, "gid": 2014, "group": "shiyanlou", "md5sum": "0625fb20347d4ff1b5da551539be0727", "mode": "0644", "owner": "shiyanlou", "size": 1024548, "src": "/tmp/ansible-tmp-1535442301.68-247864054847999/source", "state": "file", "uid": 2030 } shiyanlou@ubunt:~$

常用參數列表

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

  1. unarchive 用於解壓文件

解壓遠程主機上的/tmp/shiyanlou.tar.gz

bash shiyanlou@ubunt:~$ ansible all -m unarchive -a src=/tmp/shiyanlou.tar.gz dest=/tmp copy=no 192.168.1.1 | SUCCESS => { "changed": true, "dest": "/tmp", "extract_results": { "cmd": [ "/usr/bin/gtar", "--extract", "-C", "/tmp", "-z", "-f", "/tmp/shiyanlou.tar.gz" ], "err": "", "out": "", "rc": 0 }, "failed": false, "gid": 0, "group": "shiyanlou", "handler": "TgzArchive", "mode": "01777", "owner": "shiyanlou", "size": 4096, "src": "/tmp/shiyanlou.tar.gz", "state": "directory", "uid": 0 } shiyanlou@ubunt:~$

常用參數列表

| 參數 | 選項或默認值 | 說明 | | ---------- | ------------ | ------------------------------------------------------------ | | copy | yes or no | 在解壓文件之前,是否先將文件複製到遠程主機,若為no,則要求目標主機上壓縮包必須存在; | | creates | | 指定一個文件名,當該文件存在時,則解壓指令不執行 | | dest | | 遠程主機上的一個路徑,即文件解壓的路徑 | | group | | 解壓後的目錄或文件的屬組 | | list_files | yes or no | 如果為yes,則會列出壓縮包里的文件,默認為no,2.0版本新增的選項 | | mode | | 解壓後文件的許可權 | | src | yes or no | 如果copy為yes,則需要指定壓縮文件的源路徑 | | owner | | 解壓後文件或目錄的屬主 |

  1. file 用於遠程主機上的文件操作

刪除遠程主機上的/tmp/shiyanlou.tar.gz文件

bash shiyanlou@ubunt:~$ ansible all -m file -a "path=/tmp/shiyanlou.tar.gz state=absent" 192.168.1.1 | SUCCESS => { "changed": true, "failed": false, "path": "/tmp/shiyanlou.tar.gz", "state": "absent" } shiyanlou@ubunt:~$

常用參數列表

| 參數 | 選項或默認值 | 說明 | | --------- | ------------ | ------------------------------------------------------------ | | force | yes or no | 需要在兩種情況下強制創建軟鏈接,一種是源文件不存在但之後會建立的情況下;另一種是目標軟鏈接已存在,需要先取消之前的軟鏈,然後創建新的軟鏈 | | group | | 定義文件/目錄的屬組 | | mode | | 定義文件/目錄的許可權 | | owner | | 定義文件/目錄的屬主 | | path 必選 | | 定義文件/目錄的路徑 | | recurse | | 遞歸的設置文件的屬性,只對目錄有效 | | src | | 要被鏈接的源文件的路徑,只應用於state=link的情況 | | dest | | 被鏈接到的路徑,只應用於state=link的情況 |

  1. raw 用於執行遠程系統命令,支持管道傳遞

查看遠程主機tmp/shiyanlou/下的文件inventory.py

bash shiyanlou@ubunt:~$ ansible all -m raw -a "ls -al /tmp/shiyanlou | grep inventory" 192.168.1.1 | SUCCESS | rc=0 >> -rw-rw-r-- 1 shiyanlou shiyanlou 0 Aug 28 16:11 inventory.py Shared connection to 192.168.1.1 closed. shiyanlou@ubunt:~$

  1. fetchcopy模塊相反,從遠處主機下載文件

將遠程主機上的/tmp/inventory.py拷貝至Ansible server的/tmp目錄下

bash shiyanlou@ubunt:~$ ansible all -m fetch -a "src=/tmp/shiyanlou/inventory.py dest=/tmp/ owner=shiyanlou group=shiyanlou mode=0644" 192.168.1.1 | SUCCESS => { "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/tmp/192.168.1.1/tmp/shiyanlou/inventory.py", "failed": false, "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "remote_md5sum": null } shiyanlou@ubunt:~$

常用參數

| 參數 | 選項或默認值 | 說明 | | ----------------- | ------------ | ------------------------------------------------------------ | | dest 必選 | | 用於保存文件的目錄 | | fail_on_missing | yes or no | 設置為「yes」時,如果由於任何原因無法讀取遠程文件,則任務將失敗。在Ansible-2.4之前,只有在缺少源文件時才設置此項 | | flat | | 將hostname/path/複製到/file時允許重命名文件,如果dest以/結尾,它將使用源文件的基名,類似於copy模塊 | | src 必選 | | 要獲取的遠程系統上的文件。這必須是文件,而不是目錄。在以後的版本中可能支持遞歸提取 | | validate_checksum | yes or no | 獲取文件後,驗證源和目標校驗和是否匹配 |

Ansible模塊的使用官方文檔都有詳細的介紹,這裡不一一列舉,用戶也可以根據業務需求開發自己的模塊。

4.4 Playbook基礎與實戰

Playbook是Ansible的配置,部署,編排語言。他們可以被描述為一個需要希望遠程主機執行命令的方案,或者一組IT程序運行的命令集合。可用於伺服器環境的初始化,保持機器配置統一,執行簡單的日常任務。Playbook還開創了很多特性,它可以允許你傳輸某個命令的狀態到後面的指令,如你可以從一台機器的文件中抓取內容並附為變數,然後在另一台機器中使用,這使得你可以實現一些複雜的部署機制,這是Ansible命令無法實現的。

4.4.1 Playbook基礎組件

  1. 主機(hosts)和用戶(users) hosts用於指定要執行任務的主機,remote_user則用於指定遠程主機上的執行任務的用戶
  2. 任務列表(Tasks) task列表中的各任務按次序逐個在hosts中指定的主機上執行,即在所有主機上完成第一個任務後再開始第二個任務。在運行Playbook 時(從上到下執行),如果一個host執行task失敗,這個host將會從整個playbook的rotation中移除,如果發生執行失敗的情況,需修正playbook 中的錯誤,然後重新執行
  3. 變數(variables)模板(template) 變數可以在Playbook中定義也可以在inventory中定義,Ansible使用f="http://jinja.pocoo.org/docs/2.10/">Jinja2模板,在task或template中引用變數的方式為{{ var_name }}
  4. 處理器(handlers) 也是一些task的列表,通過名字來引用,它們和一般的task並沒有什麼區別;由通知者進行notify,如果沒有被notify,handlers不會執行
  5. 註冊(Register) 存儲某個命令的結果到變數中,以備日後訪問是很有用的。

4.4.2 Playbook執行四步走

很多同學喜歡Playbook寫好之後直接執行,這不是一個好的習慣!科學的過程應該按照如下四步來:

  1. 檢查Playbook語法

bash $ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --syntax-check

  1. 列出要執行的主機

bash $ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --list-hosts

  1. 列出要執行的任務

bash $ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --list-tasks

  1. 運行Playbook

bash $ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml

4.4.2 Playbook實戰演練

寫一個Playbook shiyanlou.yml,要求如下:

  • 通過用戶shiyanlou執行任務,不搜集目標主機信息
  • 要求執行其它任務前先檢測主機連通性
  • /home/shiyanlou/shiyanlou.tar.gz拷貝至主機的/tmp目錄,並設置文件所有者和所屬組為shiyanlou,文件許可權為-rw-r--r--
  • 解壓shiyanlou.tar.gz/tmp目錄
  • 如果解壓成功,則刪除主機上的shiyanlou.tar.gz,並創建目錄/tmp/shiyanlou_com/

- hosts: all remote_user: shiyanlou gather_facts: no tasks: - name: test connection ping: tags: - always - name: copy shiyanlou.tar.gz to /tmp copy: backup=yes src=/home/shiyanlou/shiyanlou.tar.gz dest=/tmp owner=shiyanlou group=shiyanlou mode=0664 tags: - shiyanlou - name: unarchive shiyanlou.tar.gz to /tmp unarchive: copy=no src=/tmp/shiyanlou.tar.gz dest=/tmp list_files=yes notify: - delete shiyanlou.tar.gz - create a file named in inventory handlers: - name: delete shiyanlou.tar.gz file: path=/tmp/shiyanlou.tar.gz state=absent - name: create a file named in inventory file: path=/tmp/{{ file }} state=directory

首先,分別檢查Playbook的語法格式是否正確,列出要執行的主機和任務

shiyanlou@ubunt:~$ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --syntax-checkplaybook: shiyanlou.ymlshiyanlou@ubunt:~$ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --list-hostsplaybook: shiyanlou.yml play #1 (all): all TAGS: [] pattern: [uall] hosts (1): 192.168.1.1shiyanlou@ubunt:~$ ansible-playbook -i /etc/ansible/hosts shiyanlou.yml --list-tasksplaybook: shiyanlou.yml play #1 (all): all TAGS: [] tasks: test connection TAGS: [always] copy shiyanlou.tar.gz to /tmp TAGS: [shiyanlou] unarchive shiyanlou.tar.gz to /tmp TAGS: []shiyanlou@ubunt:~$

其中,tags用於指定執行Playbook時只執行其中一個或多個task,tags: -always表示無論執行哪一個tags時,定義有always的tags都會執行。如只執行task copy shiyanlou.tar.gz to /tmp

shiyanlou@ubunt:~$ ansible-playbook shiyanlou.yml --tags="shiyanlou"PLAY [all] ***************************************************************************************TASK [test connection] ***************************************************************************************ok: [192.168.1.1]TASK [copy shiyanlou.tar.gz to /tmp] ***************************************************************************************changed: [192.168.1.1]PLAY RECAP ***************************************************************************************192.168.1.1 : ok=2 changed=1 unreachable=0 failed=0shiyanlou@ubunt:~$

完整執行結果如下:

shiyanlou@ubunt:~$ ansible-playbook shiyanlou.ymlPLAY [all] ***************************************************************************************TASK [test connection] ***************************************************************************************ok: [192.168.1.1]TASK [copy shiyanlou.tar.gz to /tmp] ***************************************************************************************changed: [192.168.1.1]TASK [unarchive shiyanlou.tar.gz to /tmp] ***************************************************************************************changed: [192.168.1.1]RUNNING HANDLER [delete shiyanlou.tar.gz] ***************************************************************************************changed: [192.168.1.1]RUNNING HANDLER [create a file named in inventory] ***************************************************************************************changed: [192.168.1.1]PLAY RECAP ***************************************************************************************192.168.1.1 : ok=5 changed=4 unreachable=0 failed=0shiyanlou@ubunt:~$

4.5 實現動態Inventory

所謂動態Inventory,就是通過外部腳本獲取主機列表,並按照hosts文件所要求的格式將主機分組,而不是通過人工編輯來維護/etc/ansible/hosts文件。一般會結合自動化運維繫統中的CMDB資產管理、Zabbix監控系統、Crobble安裝系統、雲計算平台等獲取主機信息。

示例使用定義好的主機列表,通過Python3實現自動生成hosts文件,為192.168.0.0/16網段的主機添加變數file,供Playbook執行時調用。vim /home/shiyanlou/inventory.py:

#!/usr/bin/python3# -*- coding:utf-8 -*-# __author__ = liao gao xiangdef inventory_sync(): """自動同步Ansible Inventory""" hosts = [192.168.1.1, 192.168.2.2, 172.19.1.1, 172.19.1.2] ansible_hosts = open("/etc/ansible/hosts", "w") ansible_hosts.write("[all]
") for host in hosts: if host.startswith("192.168."): ansible_hosts.write("{} file={}
".format(host, "shiyanlou_com")) else: ansible_hosts.write("{}
".format(host)) ansible_hosts.write("[all:vars]
") ansible_hosts.write("ansible_ssh_user=shiyanlou
") ansible_hosts.write("ansible_ssh_pass=shiyanlou
") ansible_hosts.close()if __name__ == "__main__": inventory_sync()

運行python3 inventory.py,生成的hosts文件如下

shiyanlou@ubunt:~$ cat /etc/ansible/hosts[all]192.168.1.1 file=shiyanlou_com192.168.2.2 file=shiyanlou_com172.19.1.1172.19.1.2[all:vars]ansible_ssh_user=shiyanlouansible_ssh_pass=shiyanloushiyanlou@ubunt:~$

當然,在實際的自動化運維或DevOps實踐中不會這麼簡單,hosts文件可以按業務場景不同分成多個,從其它資產管理系統獲取的主機信息需要實時更新,可通過Celery等後台任務實現;腳本也需要加入try...except...else...finally捕獲可能存在的錯誤,並記錄同步日誌。

五、實驗總結

Ansible是自動化運維和DevOps中持續部署的必備神器,通過Playbook的自動化任務可以解放運維工作量。本實驗從軟體的介紹和安裝開始,詳細的講解了Ansible命令的使用,常用模塊,從基本概念到原理,到實踐全覆蓋。真正用好Ansible需要花時間學習和鑽研,新版Ansible 2.6提供了比較友好的API,可以進行二次開發,或與公司現有的運維繫統對接,這個艱巨的任務就交給各位大佬吧^_^

六、課後習題

寫一個劇本,實現自動化安裝MySQL 5.6,並設置為UTF-8編碼(提示:更改my.cnf文件然後上傳)

七、參考鏈接

Ansible v2.4 官方文檔

Ansible ping 模塊報錯集錦

推薦閱讀:

linux擴展正則表達式
苦背Linux命令,不如實例操作
使用樹莓派和 projectx/os 託管你自己的電子郵件
運用虛擬機搭建本地Hadoop環境
自學shell之find

TAG:Python | Linux | MySQL |