Ansible

是否可以在 Ansible 上定義 run_once 策略?

  • July 13, 2019

我想只在一台帶有 Ansible 的主機上執行任務。為此,我使用參數run_once

但真正令人震驚的是能夠指定一種策略來選擇一個主機來執行該任務。例如,具有最高可用記憶體的主機。

如果它存在於在 libvirt 集群上創建新虛擬機的劇本中,我計劃使用此功能。

據我所知,沒有這樣的綜合機制。該任務將從清單中的第一個主機開始,具體取決於您的遊戲中匹配的內容(即hosts參數),最終是您在命令行上使用的限制(即 ansible playbook 的選項),如果是-l,將在此之後停止run_once用過的。

同時,我認為有一種方法可以實現您的目標。

背景資料

  • Ansible 維護了一些神奇的變數,其中包括:

    • ansible_play_hosts- 目前播放中的活動主機列表受串列限制,即“批處理”
    • hostvars- 一個雜湊圖,其中包含清單中的所有主機和分配給它們的變數
  • 每個主機上的可用記憶體在ansible_memfree_mb. 僅當您在主機上收集事實時,此變數才存在(即您沒有gather_facts: no在遊戲中關閉它)

  • 該解決方案使用兩個過濾器,您可能希望對其進行更深入的了解

    • map允許我們僅從中提取相關的主機資訊hostvars
    • json_query(實現jmespath)允許我們過濾尋找最大記憶體的變數列表,並在最終僅獲取相關節點的主機名

建議的解決方案

下面的劇本展示瞭如何結合上述元素來擊中目標。該任務使用 , 和 的組合,run_once以便它在特定主機上執行,就好像它首先被選中一樣。delegate_to``delegate_facts

---
- name: Delegate single running task to dynamically chosen host
 hosts: all
 gather_facts: true

 vars:
   max_mem_query: max_by(@, &ansible_memfree_mb).inventory_hostname
   selected_host: >-
     {{
       ansible_play_hosts |
       map('extract', hostvars) |
       list |
       json_query(max_mem_query)
     }}

 tasks:
   - name: Run a command on host with most memory
     debug:
       msg: "I would run on host {{ inventory_hostname }}"
     run_once: true
     delegate_to: "{{ selected_host }}"
     delegate_facts: true

注意:我僅針對具有兩個本地 docker 實例的清單對此進行了測試,以驗證我的劇本,因此輸出並不真正相關(所有實例都具有相同的可用記憶體,選擇了第一個恰好委託給自己的實例)。但我很有信心它會起作用,如果沒有,我準備編輯它以適應一些最終的怪癖。

引用自:https://unix.stackexchange.com/questions/529848