一 引言 前段時間自己實現了ansible對接操作系統升級腳本,現將整個項目記錄如下,如果項目中存在問題或優化的點,請幫忙指正。本項目運行在RedHat Linux系統。 在我們生產環境中,操作系統的升級由系統升級、伺服器重啟以及vmtools安裝三部分組成。本次項目的目標有兩點: (1) ansi ...
一 引言
前段時間自己實現了ansible對接操作系統升級腳本,現將整個項目記錄如下,如果項目中存在問題或優化的點,請幫忙指正。本項目運行在RedHat Linux系統。
在我們生產環境中,操作系統的升級由系統升級、伺服器重啟以及vmtools安裝三部分組成。本次項目的目標有兩點:
(1) ansible對接操作系統升級腳本實現自動批量升級伺服器系統。
(2) 系統升級、伺服器重啟和vmtools安裝三部分即可以統一運行又可各部分獨立運行。
存在的難點:在實現中,如何實現伺服器重啟部分和其餘兩個部分的銜接。這裡需要考慮以下幾點:
(1) 如何判斷伺服器是否需要重啟?
(2) 如何判斷伺服器是否重啟成功?
(3) 如何避免伺服器重啟過程中ansible會話的斷開?
具體的實現過程以及難點解決方法將在後續的項目介紹中展示。
二 項目介紹
圖1 項目中playbook的運行流程
在項目中我們創建一個單獨的ansible角色,角色名為update_os。整個ansible角色分為檢測任務、主機升級任務、重啟任務、vmtools安裝任務。各任務的功能如下:
- 檢測任務: 判斷主機是否線上。
- 主機升級任務: 升級操作系統、記錄升級日誌、判斷升級是否成功。
- 重啟任務: 判斷主機是否升級成功、重啟伺服器、判讀主機重啟是否成功。
- vmtools安裝任務: 安裝vmtools、記錄安裝日誌、判斷是否安裝成功。
各個playbook的內容:
site.yml文件是updata_os角色的入口,使用roles導入update_so角色。
---
- name: update os
gather_facts: no
hosts: test
roles:
- update_os
update_os角色的tasks目錄中的文件有main.yml、ping.yml、 update.yml、reboot.yml、install_vmtools.yml五個playbook文件。
main.yml文件的內容如下:
---
- name: check if host is online
include: ping.yml
tags: always
- name: Start system upgrade
block:
- name: decide to proceed
setup:
tags: always
- name: include update playbook
include_tasks:
file: update.yml
apply:
tags: update_os
tags: always
- name: include reboot playbook
include_tasks:
file: reboot.yml
apply:
tags: reboot_singal
tags: always
- name: include vmtools playbook
include_tasks:
file: install_vmtools.yml
apply:
tags: vmtools
tags: always
when: >
( ping.failed is defined and ping.failed == false ) or
( ping2.failed is defined and ping2.failed == false )
main.yml文件中實現對其餘四個playbook文件的調用。在main.yml文件中先導入ping.yml文件來檢測線上的主機,之後只對線上的主機執行block塊(Start system upgrade)中的內容。main.yml文件中之後依次導入update.yml, reboot.yml和install_vmtools.yml三個playbook。main.yml文件中也使用了ansible的tags功能,這樣可以實現主機升級、重啟、安裝vmtools三個任務既可以單個執行又可以統一執行,適用於多種場景的使用。例如:
]# ansible-playbook site.yml # 統一執行
]# ansible-playbook site.yml --tags update_os #只執行標簽update_os即主機升級任務
ping.yml文件內容如下:
---
- name: test if linux is alive
block:
- name: 1st ping linux
ping:
register: ping
failed_when: false
ignore_unreachable: yes
ignore_errors: yes
- name: 2nd ping linux
ping:
register: ping2
failed_when: false
ignore_unreachable: yes
ignore_errors: yes
when: >
(ping.failed is defined and ping.failed == true) or
(ping.unreachable is defined and ping.unreacheable == true)
when: (ansible_connection is defined) and ((ansible_connection == 'ssh') or (ansible_connection == ''))
ping.yml文件的編寫機製為: 第一次對受控主機執行ansible的ping模塊,並使用register記錄結果。 對於第一次ping失敗時的主機,playbook將執行第二次ping。第二次ping的原因是為了避免網路抖動等因素導致第一次ping失敗。只有第一次或第二次ping成功的受控主機才進行之後的任務。
三 參考文獻
- https://github.com/skippie81/ansible-os-update
- https://github.com/D34m0nN0n3/ansible-update-os
- https://github.com/joe-speedboat/ansible.os_update