如何在 Ansible Playbooks 中使用處理程序


處理程序 像正常的 ansible 任務一樣,它只在收到通知時運行。處理程序是一個非常有用且重要的概念 Ansible..

執行處理程序任務涉及兩條指令。

  • 通知說明 這將向您正在執行的任務發送觸發信號。
  • 處理程序指令 在此之下,任務被分組在一起。

讓我們談談一個真實的用例。 假設您要創建一個 SSH 增強手冊,對 ssh 配置文件進行一些更改。

如您所知,當您更改配置時,您需要重新啟動服務才能使更改生效。這是處理程序非常有效的地方。

當 sshd 配置文件中的任務發生更改時,您可以發出重新啟動任務的信號。 sshd 服務。

內容

  1. Ansible handler的關鍵點
  2. 調用多個任務
  3. 執行順序
  4. 只運行一次
  5. 重複任務
  6. 處理任務失敗
    1. 1. 強制處理程序
    2. 2.忽略錯誤
  7. 閃存處理程序
  8. 使用“listen”運行處理程序任務
  9. 結論是

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
元 Ansible 文檔元——Ansible 文檔

閃存處理程序 執行所有發出通知指令的任務。

- 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 管理