如何在 Ansible 劇本中使用處理程序


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

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

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

讓我們談談真實的用例。 我想寫一本 SSH 加固手冊,對 ssh 配置文件進行一些更改。

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

您可以在 sshd 配置文件中的任務更改時向任務發送信號以重新啟動。 sshd 服務。

內容

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

Ansible 處理程序關鍵點

在我們進入動手部分之前,讓我們了解一些關於處理程序的要點。

  • 僅當父任務已更改 (changed=true) 時才會執行處理程序任務。
  • 處理程序任務僅在每次播放結束時運行,但您可以選擇在任何地方運行它們。
  • 無論您在單個主機上調用多少次相同的處理程序任務,處理程序任務都只會運行一次。
  • 任務名稱必須是唯一的。 如果兩個任務具有相同的名稱,則只有第一個任務會運行。
  • 任務按照處理程序指令中定義的順序執行,而不是調用通知指令的順序。

句法

要定義處理程序任務, 消息 什麼時候 處理程序 您必須使用該指令。 Notify 指令表示處理程序任務的執行。

下面是一個示例劇本。處理程序指令定義了兩個任務。要運行這些任務,請使用 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

檢查上面的腳本。第一個任務(獲取主機名)調用處理程序任務(打印主機名)。 第二個任務是調用第二個處理程序任務(Print IP)。

當 playbook 運行時,它首先運行兩個任務並向處理程序發送信號。所有任務完成後,將執行處理程序任務。

執行順序

當心: 不管處理程序任務如何被調用,它們都按照處理程序指令定義的順序執行。

只運行一次

同一個處理程序任務可以被多次調用,但處理程序任務只會運行一次。

我們正在運行我們在上一節中使用的相同 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 讀取的第一個任務,忽略所有其他同名任務。

查看下面的任務,兩個任務名稱相同。 當您運行 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 ]"

看下圖,第一個任務的輸出運行成功,並且正在通知處理程序任務運行,但是同一主機中的下一個任務失敗,因此處理程序任務未運行。

任務失敗 - 輸出任務失敗 – 輸出

讓我們看看如何使用不同的選項來處理任務失敗。

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“,您可以將多個任務分組並使用 notify 語句將它們全部運行。這是使用處理程序時標籤的一個很好的替代方案。

如果你看到下面的腳本,你就設置好了 “所有使命” 並通過 消息 指導。

- 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 PlaybookAnsible 系列Ansible 教程DevOpsHandlersITAutomationLinuxLinux 管理