Orange的運維學習日記–47.Ansible進階之異步處理
文章目錄
- Orange的運維學習日記--47.Ansible進階之異步處理
- Playbook 執行順序原理
- 可選執行策略
- 調整并發連接數:forks 參數
- 查看與修改 forks
- 性能調優建議
- 分批執行全局任務:serial 關鍵字
- serial 用法示例
- 應用場景與注意
- 異步任務與后臺執行:async 與 poll
- 異步示例
- 后臺任務跟蹤:async_status
- 狀態檢測:wait_for 模塊
- 文件存在檢測
- TCP 端口檢測
- 實踐建議與最佳實踐
Playbook 執行順序原理
當 Ansible 運行 playbook 時 會按 playbook 中定義的 play 順序依次執行
每個 play 里 對所有目標主機按批次完成一個任務后 再統一進入下一個任務
該行為源自默認的 linear 策略 旨在保持任務執行流程可預期
在執行過程中
- Ansible 控制節點會對 hosts 列表建立 SSH 連接池
- 按照 forks 配置 對一批主機同時發起任務
- 等所有批次完成當前任務后 才會調度下一個任務
- 直到所有任務在所有主機上執行完畢 后釋放連接
該模型在少量主機時表現穩定 可充分利用并發優勢
當管理數百甚至上千臺主機時 過多并發會對控制節點產生顯著負載
可選執行策略
Ansible 支持多種執行策略
- linear(默認) 按照上文所述批次執行
- free 在單個主機執行完任務后 立即執行下一個任務 無需等待其他主機
- debug 用于調試 playbook 記錄詳細執行信息
選擇不同策略 會對批量運維場景帶來靈活度與安全性的平衡
調整并發連接數:forks 參數
forks 定義 Ansible 在同一時刻可并行啟動的 SSH 連接數
默認值較低 為 5 以避免對控制節點和目標節點造成過大壓力
查看與修改 forks
在命令行中可查詢當前值
ansible-config dump | grep DEFAULT_FORKS
在 ansible.cfg 中修改后生效
[defaults]
forks = 20
也可在執行 playbook 時通過 -f
或 --forks
覆蓋
ansible-playbook playbook.yaml --forks 10
性能調優建議
- 管理大量 Linux 主機時 模塊大多在目標主機執行 控制節點壓力小 可適當提高 forks(如 50~100)
- 管理網絡設備或其它非 Linux 設備時 模塊執行更依賴控制節點 需謹慎提升 forks 防止 CPU 或內存瓶頸
- 可結合監控工具 實時觀察控制節點負載 并根據實際情況動態調整
分批執行全局任務:serial 關鍵字
serial 可對整個 play 進行批量拆分 先讓部分主機完成 play 中所有任務 再依次切換到下一批
常見場景包括滾動升級 Web 集群 或在高可用環境中進行安全補丁更新
serial 用法示例
將所有主機分成兩臺一組 執行完整部署流程
---
- name: Rolling update of httpdhosts: webserversserial: 2tasks:- name: install latest httpdyum:name: httpdstate: latestnotify: restart httpdhandlers:- name: restart httpdservice:name: httpdstate: restarted
也可使用百分比表示 批次大小根據主機總數自動計算 最小為 1
serial: 25%
應用場景與注意
- 在批量下線或升級時 避免所有實例同時不可用
- 可與 health check 腳本結合 在每批次完成后 驗證服務可用性
- 任務失敗時 可快速定位問題所在批次 便于回滾或重試
異步任務與后臺執行:async 與 poll
默認情況下 Ansible 會等待單個任務完成后 再調度下一個任務
對耗時操作 如大文件下載、數據庫備份、重啟服務 等 同步等待會嚴重拖慢 playbook 整體執行速度
通過 async 和 poll 實現異步執行
- async 指任務最長執行時間(秒) 超時會被強制終止
- poll 指檢查任務狀態的間隔(秒) poll: 0 則不等待 立即繼續后續任務
異步示例
將下載任務放入后臺 不阻塞后續執行
---
- name: download ISO in backgroundhosts: node1tasks:- name: fetch CentOS ISOget_url:url: http://example.com/CentOS.isodest: /home/centosasync: 600poll: 0- name: immediately start next taskdebug:msg: move on without waiting download
當 async 小于實際運行時間 時 會在超時后報錯
async: 5
poll: 2
此時若命令需 10 秒 執行將被中斷
后臺任務跟蹤:async_status
Fire-and-forget 模式需借助 async_status 模塊跟蹤完成狀態
---
- name: start long taskhosts: node1tasks:- shell: sleep 30async: 60poll: 0register: job- name: wait for async task to finishasync_status:jid: "{{ job.ansible_job_id }}"register: job_resultuntil: job_result.finishedretries: 10delay: 5
結合 retries 和 delay 可控制最大等待時長 與檢查頻率
狀態檢測:wait_for 模塊
當異步操作與外部條件掛鉤時 可使用 wait_for 模塊對文件、端口或服務狀態進行檢測
- path 用于等待文件或目錄的創建或刪除
- host 與 port 用于檢測 TCP 端口就緒或關閉
- delay、sleep、timeout 分別定義首次等待、檢查間隔和最長超時
文件存在檢測
---
- name: wait for file creationhosts: node1tasks:- shell: sleep 10 && touch /tmp/readyasync: 20poll: 0register: async_job- name: wait until /tmp/ready appearswait_for:path: /tmp/readystate: presentdelay: 5sleep: 2timeout: 60
TCP 端口檢測
---
- name: reboot and wait SSHhosts: node1,node2tasks:- name: reboot node1shell: shutdown -r now "upgrade"async: 1poll: 0when: inventory_hostname == "node1"- name: wait for node1 SSH servicewait_for:host: node1port: 22state: starteddelay: 10sleep: 5timeout: 300when: inventory_hostname == "node2"
實踐建議與最佳實踐
- 對易阻塞的操作優先考慮異步模式 并結合 async_status 或 wait_for 實現可靠回調
- 根據運維場景選擇合適批次策略 linear、free 或使用 serial 實現滾動升級
- 在控制節點部署時 分配足夠 CPU 和內存 并結合監控工具觀察 forks 設置對節點負載的影響
- 定期評估 playbook 執行策略 與并發配置 確保在目標環境持續穩定運行
de2"
------## 實踐建議與最佳實踐- 對易阻塞的操作優先考慮異步模式 并結合 async_status 或 wait_for 實現可靠回調
- 根據運維場景選擇合適批次策略 linear、free 或使用 serial 實現滾動升級
- 在控制節點部署時 分配足夠 CPU 和內存 并結合監控工具觀察 forks 設置對節點負載的影響
- 定期評估 playbook 執行策略 與并發配置 確保在目標環境持續穩定運行
- 在大型關鍵環境中 可考慮搭建 Ansible Tower 或 AWX 進一步提升并發調度與任務可視化管理能力