배경 정보

배경 정보

하나의 호스트에서만 Ansible을 사용하여 작업을 실행하고 싶습니다. 이를 위해 나는 매개변수를 사용합니다 run_once.

하지만 정말 놀라운 점은 작업을 실행할 호스트를 선택하는 정책을 지정할 수 있다는 것입니다. 예를 들어 사용 가능한 메모리가 가장 높은 호스트입니다.

libvirt 클러스터에 새 VM을 생성하는 플레이북에 이 기능이 있으면 사용할 계획입니다.

답변1

내가 아는 한, 그러한 포괄적인 메커니즘은 없습니다. 작업은 게임에서 일치하는 항목(예: 매개변수 hosts)과 궁극적으로 명령줄에서 사용하는 제약 조건(예: -lAnsible 플레이북에 대한 옵션) 에 따라 인벤토리의 첫 번째 호스트에서 시작되고 해당 호스트에서 실행됩니다. 그런 다음 ( 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 인스턴스가 있는 매니페스트에 대해서만 테스트했기 때문에 출력은 실제로 관련성이 없습니다(모든 인스턴스는 사용 가능한 메모리가 동일하고 선택한 첫 번째 인스턴스는 자체적으로 위임됩니다). 하지만 나는 그것이 효과가 있을 것이라고 확신하며, 전부는 아니더라도 몇 가지 최종적인 문제를 수용하기 위해 편집할 준비가 되어 있습니다.

관련 정보