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

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

  • 通知命令 這將向要執行的任務發送觸發信號。
  • 處理指令 哪些任務組合在一起。

讓我們談談實際用例。 假設我們要編寫一個 SSH 強化手冊,對 ssh 配置文件進行一些更改。

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

當任務對 sshd 配置文件進行更改時,您可以向該任務發送一個信號,告知它應該重新啟動。 sshd 服務。

內容

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

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
元 - 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 劇本中使用通知和處理程序指令來實現各種目標。

我們還討論瞭如何使用兩種不同的選項來處理任務失敗。最後,我們將通過向您展示如何使用 listen 指令觸發多個任務來結束本文。

資源:

  • 處理程序:對更改執行操作

AnsibleAnsible 命令Ansible 劇本Ansible 系列Ansible 教程DevOpsHandlersIT 自動化LinuxLinux 管理