處理程序 像正常的 ansible 任務一樣,它只在收到通知時運行。處理程序是一個非常有用且重要的概念 Ansible..
執行處理程序任務涉及兩條指令。
- 通知說明 這將向您正在執行的任務發送觸發信號。
- 處理程序指令 在此之下,任務被分組在一起。
讓我們談談一個真實的用例。 假設您要創建一個 SSH 增強手冊,對 ssh 配置文件進行一些更改。
如您所知,當您更改配置時,您需要重新啟動服務才能使更改生效。這是處理程序非常有效的地方。
當 sshd 配置文件中的任務發生更改時,您可以發出重新啟動任務的信號。 sshd
服務。
內容
Ansible handler的關鍵點
在我們深入實踐部分之前,讓我們了解一些關於處理程序的要點。
- 處理程序任務僅在父任務更改時運行 (changed = true)。
- 處理程序任務僅在每次播放結束時運行,但您可以選擇在任何您喜歡的地方運行它。
- 無論您在單個主機上調用多少次相同的處理程序任務,處理程序任務都只會運行一次。
- 任務名稱必須是唯一的。 如果兩個任務同名,則只執行第一個任務。
- 任務按照處理程序指令定義的順序執行,而不是按照調用通知指令的順序執行。
句法
定義處理程序任務 消息 什麼時候 處理程序 您需要使用指令。 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 時,首先執行兩個任務,並向處理程序發送一個信號。當所有任務都完成後,處理程序任務將被執行。
當心: 它按照處理程序指令定義的順序執行,而不管處理程序任務如何被調用。
只運行一次
您可以多次調用同一個處理程序任務,但處理程序任務只運行一次。
我正在運行上一節中使用的相同劇本,但我更改了 notify 指令以調用相同的處理程序任務(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 讀取的第一個任務,而忽略所有其他同名任務。
查看下面的任務,兩個任務名稱相同。當您運行 playbook 時,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 ]"
看下圖,第一個任務的輸出是運行成功並通知handler任務運行,但是同一個宿主機下的下一個任務失敗了,所以handler任務運行了。不是…

讓我們看看如何使用不同的選項來處理任務失敗。
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 playbook 中使用通知和處理程序指令來實現不同的目標。
我們還看到瞭如何使用兩種不同的選項來處理任務失敗。最後,我們通過使用listen指令觸發多個任務來結束這篇文章。
資源:
- 處理程序:對更改採取措施
AnsibleAnsible 命令 AnsiblePlaybooksAnsible 系列Ansible 教程DevOpsHandlersITAutomationLinuxLinux 管理