處理程序 就像 ansible 中的普通任務一樣,它們只會在收到通知時運行。處理程序是一個非常有用和重要的概念 Ansible的.
處理程序任務的執行涉及兩條指令。
- 通知命令 這將向要執行的任務發送觸發信號。
- 處理指令 哪些任務組合在一起。
讓我們談談實際用例。 假設我們要編寫一個 SSH 強化手冊,對 ssh 配置文件進行一些更改。
如您所知,需要重新啟動服務才能使配置更改生效。這是處理程序非常有效的地方。
當任務對 sshd 配置文件進行更改時,您可以向該任務發送一個信號,告知它應該重新啟動。 sshd
服務。
內容
Ansible 處理程序關鍵點
在我們開始動手操作之前,讓我們了解一些關於處理程序的要點。
- 處理程序任務只會在父任務發生更改(更改=真)時運行。
- 處理程序任務僅在每次播放結束時運行,但您可以選擇在任何需要的地方運行它們。
- 無論您在單個主機上調用同一個處理程序任務多少次,處理程序任務都只會運行一次。
- 任務名稱必須是唯一的。 如果兩個任務具有相同的名稱,則只會運行第一個任務。
- 任務按照處理程序指令中定義的順序執行,而不是按照調用通知指令的順序執行。
句法
要定義處理程序任務, 注意 和 處理程序 您必須使用該指令。 Notify 指令指示處理程序任務的執行。
下面是一個示例劇本。 我在 handler 指令下定義了兩個任務。要運行這些任務,請使用 notify 指令,將任務名稱作為值傳遞。
- name: Handlers testing hosts: ubuntu.anslab.com gather_facts: false tasks: - name: Get the hostname shell: hostname -s register: hostname notify: print hostname handlers: - name: print hostname debug: var: hostname.stdout - name: print IP debug: var: IP.stdout
以下是劇本的輸出。儘管處理程序中有兩個任務,但只執行一個通過 notify 指令調用的任務。
調用多個任務
單個通知指令可以調用多個處理程序任務。存在 YAML
列表格式。
- name: Get the hostname shell: hostname -s register: hostname notify: - print hostname - print IP
您還可以使用 Python 列表表示法調用多個處理程序任務。
- name: Get the hostname shell: hostname -s register: hostname notify: ["print hostname", "print IP"]
執行順序
處理程序任務僅在播放結束時運行,即使它們在任務之前被調用也是如此。
- name: Handlers testing hosts: ubuntu.anslab.com gather_facts: false tasks: - name: Get the hostname shell: hostname -s register: hostname notify: print hostname - name: Get IP address of the hostname shell: hostname -I register: IP notify: print IP handlers: - name: print hostname debug: var: hostname.stdout - name: print IP debug: var: IP.stdout
檢查上面的腳本。第一個任務(獲取主機名)調用處理程序任務(打印主機名)。 第二個任務是調用第二個處理程序任務(打印 IP)。
當 playbook 運行時,它首先運行兩個任務並向處理程序發送信號。所有任務完成後,將執行處理程序任務。
當心: 無論如何調用處理程序任務,它們都按照處理程序指令定義的順序執行。
只運行一次
同一個處理任務可以被調用多次,但是處理任務只會運行一次。
我們正在運行我們在上一節中使用的相同劇本,但我們更改通知指令以調用相同的處理程序任務(print hostname
).
- name: Handlers testing hosts: ubuntu.anslab.com gather_facts: false tasks: - name: Get the hostname shell: hostname -s register: hostname notify: print hostname - name: Get IP address of the hostname shell: hostname -I register: IP notify: print hostname handlers: - name: print hostname debug: var: hostname.stdout - name: print IP debug: var: IP.stdout
從下面的輸出中可以看出,打印主機名處理程序任務只運行了一次。

重複任務
如介紹部分所述,任務應具有描述性和唯一名稱。如果定義了兩個或多個同名任務,只有ansible讀取的第一個任務會被執行,所有其他同名任務將被忽略。
查看下面的任務,兩個任務名稱相同。現在,當您運行劇本時,ansible 將運行第一個處理程序任務並打印 IP。
handlers: - name: print hostname debug: var: IP.stdout - name: print hostname debug: var: hostname.stdout

處理任務失敗
在ansible中,如果一個任務失敗,後續任務將不會運行。處理程序處理失敗的方式是,如果任何任務在特定主機上失敗,處理程序任務將不會為該主機運行,即使失敗的任務不是父任務(通知指令)。
查看下面的腳本,有兩個任務使用了 shell 模塊。第一個任務使用 /bin/true
它總是有效。此任務調用處理程序任務 (run_now)。此任務只是將消息打印到標準輸出。 第二個任務設置為失敗使用: /bin/false
.
- name: Testing handler hosts: ubuntu.anslab.com gather_facts: false tasks: - name: set a task to success shell: /bin/true notify: run_now - name: set a task to fail shell: /bin/false handlers: - name: run_now debug: msg="I am called from [ task 1 ]"
如下圖所示,第一個任務的輸出成功運行並通知處理程序任務運行,但同一主機中的下一個任務失敗,因此處理程序任務永遠不會運行。

讓我們看看如何使用不同的選項來處理任務失敗。
1. 強制處理步驟
您可以設置屬性 force_handlers: true
即使有失敗的任務,劇本也會運行處理程序任務。

您還可以使用不同的語言環境設置此參數。
- 腳本⇒
force_handlers: true
- ansible.cfg 文件 ⇒
force_handlers = true
- 命令行參數
--force-handlers
2.忽略錯誤
您還可以設置屬性 ignore_errors: true
這將忽略失敗的任務並運行處理程序任務。

沖洗程序
此時,您應該知道您的處理程序任務只會在播放結束時運行。但是有一種方法可以讓它一直工作。這可以通過元模塊來實現 沖洗程序 命令。
$ ansible-doc meta

沖洗程序 執行發出通知指令的所有任務。
- name: Testing handler hosts: ubuntu.anslab.com gather_facts: false tasks: - name: set a task to success shell: /bin/true notify: run_now - name: Run handler now meta: flush_handlers - name: set a task to fail shell: /bin/false handlers: - name: run_now debug: msg="I am called from [ task 1 ]"

從上面的輸出中可以看出,處理程序任務作為遊戲中的第二個任務運行。
使用“Listen”執行處理程序任務
到目前為止,我們已經使用任務名稱觸發了所有處理程序任務。使用”listen
“,您可以將多個任務分組並使用通知語句完成它們。在使用處理程序時,這是標籤的一個很好的替代方案。
如果你看到下面的腳本,你就設置好了 聽 到 “所有任務” 並通過 注意 指導。
- name: Testing handler hosts: ubuntu.anslab.com gather_facts: false tasks: - name: set a task to success shell: /bin/true notify: "all task" handlers: - name: handler task 1 debug: msg: This is handler task 1 listen: "all task" - name: handler task 2 debug: msg: This is handler task 2 listen: "all task" - name: handler task 3 debug: msg: This is handler task 3 listen: "all task"

結論是
本文解釋了什麼是處理程序以及如何在 ansible 劇本中使用通知和處理程序指令來實現各種目標。
我們還討論瞭如何使用兩種不同的選項來處理任務失敗。最後,我們將通過向您展示如何使用 listen 指令觸發多個任務來結束本文。
資源:
- 處理程序:對更改執行操作
AnsibleAnsible 命令Ansible 劇本Ansible 系列Ansible 教程DevOpsHandlersIT 自動化LinuxLinux 管理