![배경 정보](https://linux55.com/image/157062/%EB%B0%B0%EA%B2%BD%20%EC%A0%95%EB%B3%B4.png)
하나의 호스트에서만 Ansible을 사용하여 작업을 실행하고 싶습니다. 이를 위해 나는 매개변수를 사용합니다 run_once
.
하지만 정말 놀라운 점은 작업을 실행할 호스트를 선택하는 정책을 지정할 수 있다는 것입니다. 예를 들어 사용 가능한 메모리가 가장 높은 호스트입니다.
libvirt 클러스터에 새 VM을 생성하는 플레이북에 이 기능이 있으면 사용할 계획입니다.
답변1
내가 아는 한, 그러한 포괄적인 메커니즘은 없습니다. 작업은 게임에서 일치하는 항목(예: 매개변수 hosts
)과 궁극적으로 명령줄에서 사용하는 제약 조건(예: -l
Ansible 플레이북에 대한 옵션) 에 따라 인벤토리의 첫 번째 호스트에서 시작되고 해당 호스트에서 실행됩니다. 그런 다음 ( 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 인스턴스가 있는 매니페스트에 대해서만 테스트했기 때문에 출력은 실제로 관련성이 없습니다(모든 인스턴스는 사용 가능한 메모리가 동일하고 선택한 첫 번째 인스턴스는 자체적으로 위임됩니다). 하지만 나는 그것이 효과가 있을 것이라고 확신하며, 전부는 아니더라도 몇 가지 최종적인 문제를 수용하기 위해 편집할 준비가 되어 있습니다.