Ansible에서 with_items 루프를 병렬로 실행하는 방법이 있습니까?


12

Ansible 2.2를 실행하고 있지만 도움이된다면 업그레이드 할 수 있습니다.

내가 본 꽤 흥분했다,하지만 Ansible 문서의이 (또는) 버전에 될 것 같지 않습니다.

내가 해결하려는 문제는 Centos 상자에서 관리 해야하는 1000 명의 사용자가 있다는 것입니다.

이 작업을 연속적으로 실행하는 데 시간이 오래 걸립니다. 그리고 더 성가신 것은 사용자 모듈의 "expires"명령이 항상 변경 한 것으로 표시하기 때문에 모든 것이 변경된 것으로 표시됩니다.

이것은 또한 유망한 것처럼 보였지만 with_items 루프에서 각 명령을 실행하는 데 동일한 시간이 걸렸으며 더 이상 진행되지 않았습니다 (끝까지 갈 때까지 기다릴 염려가 없었습니다).

작업을 건너 뛰는 것은 지금 빠릅니다 (Ansible 2.0보다 훨씬 빠름).이 작업을 병렬로 수행하는 방법을 알 수 없다면 다시 돌아가서 무의미한 작업을 건너 뛰는 방법을 알아낼 것입니다. 그렇지 않으면, 나는 내 자신의 모듈을 쓸 것이다. 그러나 Ansible 에서이 모든 것을 더 빨리 할 수있는 것처럼 보입니다.


이것은 병렬로 실행하고 싶은 host_authorizations사용자 이름 및 기타 데이터의 목록입니다.

  - name: Create/modify OS user accounts
    user: name={{ item.username }} group=sshusers shell=/bin/bash home="/home/selinux-modules/{{ item.username }}" state=present expires={{item.expiredate|default(omit)}}
    with_items: "{{ host_authorizations }}"
    tags: full_maintenance

코드 스 니펫을 제공하십시오. 그렇지 않으면 도움이되지 않습니다.
030

@ 030 스 니펫이 있는데 문맥에 약간 도움이 될 것 같습니다. 동일한 호스트에서 작업을 (루프로) 병렬로 실행할 수있는 방법이 있다면 개념적으로 더 관심이 있습니다. 나는 비동기식으로 많은 개별 작업을 수행 할 수 있지만 with_items로는 그렇게 많이 할 수 없다는 것을 알고 있습니다.
피터 터너

따라서 기본적으로 1000 명의 사용자를 작성해야하는 경우 한 명의 사용자를 작성하는 것만 큼 빨리 완료해야합니다. 흥미롭고 왜 LDAP와 같은 것을 사용하지 않습니까?
030

1
진지하게, 당신은 고통의 길로 향하고 있습니다. 누구나 사용자 수가 증가하자마자 모든 사람들이 평상시 중앙 회계 시스템으로 이동한다고 가정합니다. 일부 ldap 백엔드 (활성 디렉토리 일 수 있음) 다음 만료 시간 및 공개 키를이 중앙베이스의 속성으로 설정 한 다음 sss_ssh_authorizedkeys와 같은 것을 사용하여 ssh 서버가이 중앙베이스에서 인증 된 키를 가져 오도록합니다.
Tensibai

2
나는 이것이 대단한 사용자라는 것에 동의하지 않습니다 (단지 대량의 사용자 작성 / 관리를 수행하지는 않습니다). 계정이 로컬 계정 기반에서 대량으로 관리되어서는 안된다는 점에
동의

답변:


13

@webKnja가 언급했듯이 async모드 로 가능 합니다. 나는 최근에 스스로 그것을 발견했고 당신의 필요에 따라 3 가지 다른 방법으로 그것을 사용할 수 있다는 것을 배웠다.

  1. 결과를 실행하고 폴링 합니다 poll:5. 5 초마다 결과를 폴링합니다. 이 방법으로 시간을 절약 할 수 있습니다.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 5
    
  2. Fire and forget poll: 0 , Ansible이 바로 그 작업을 수행하기 때문에 매우 빠른 옵션입니다. 단점은 우리가 작업의 결과가 무엇인지 모른다는 것 changed: True/False입니다. 물론 피드백에 관심이 있다면 단점입니다.).

    name: My long runing task
    some_module_name:
      ip: "{{item.fabric}}"
      username: "{{user}}"
      password: "{{password}}"
      secret: "{{secret}}"
    loop: "{{zoning_list}}"
    register: _alias_vc_0
    async: 60
    poll: 0
    
  3. 화재와 함께 잊지async_status 작업에 대한 구문 예와 동일한 2 는 추가 작업이 필요합니다 whowever async_status. 이것은 비교적 빠르기 때문에 (나보다 빠른 일반 루핑 또는 execute and poll) 내가 좋아하는 registerasync_task입니다.

    retries: 20 -실패하기 전에 몇 번의 시도.

    delay: 2 -설문 조사 사이에 몇 초 동안 대기해야합니까?

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 0
    
    
    - name: Wait for My long running task to finish
      async_status:
        id: "{{ item.ansible_job_id }}"
      register: _jobs_alias_vc_0
      retries: 20
      delay: 2
      until: _jobs_alias_vc_0.finished
      loop: "{{_alias_vc_0.results}}"
    

작업에 따라 주의 사항async옵션 을 사용하지 못할 수 있습니다. 동일한 리소스에 대한 여러 요청을 처리 할 수없는 시스템과 상호 작용하는 예제가 있습니다. async여러 호스트에서 동일한 작업을 수행해야하는 경우 옵션이 가장 효과적이라는 것을 알았습니다 . 내가 가장 많이 "저장"할 수 있었던 곳입니다.

질문에 Ansible documentation에 대한 링크를 게시 했으므로 그렇게하지 않을 것입니다.


@chicks poll예제 3에서 값을 0 으로 변경하려고 할 수 있습니다. 이것은 놀라운 설명입니다! Thnx.
Debanjan Basu

@DebanjanBasu 누구나 제안 된 편집을 할 수 있습니다. 검토 대기열에서 승인 한 사람 일 수도 있지만 편집 자체에 대한 크레딧을 받아야합니다.
병아리

하나의 문자 편집은 슬프게도 허용되지 않습니다! :(
Debanjan Basu

2
옵션 3은 훌륭하게 작동합니다. 그러나 한 가지 의견 : Ansible 2.8 이상 async_status에서는 jid, not이 필요합니다 id.
EdwardTeach

4

귀하의 질문에 대답하려면 : 아니오, 현재 Ansible은 루프를 병렬로 실행할 수 없습니다.

newusers대신 대량 사용자 생성을 위해 사용 합니다. 모든 사용자가 포함 된 파일을 작성하고 호스트로 복사 newusers /path/to/user/list한 후 command태스크 에서 실행하십시오 .


3

이를 사용하여 async모드 를 달성 할 수 있습니다. 이 작업을 수행하는 방법에 대한 몇 가지 참고 자료를 아래에서 찾으십시오.

참조 :

---

- name: Run tasks in parallel
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Pretend to create instances
      command: "sleep {{ item }}"  # Instead of calling a long running operation at a cloud provider, we just sleep.
      with_items:
        - 6
        - 8
        - 7
      register: _create_instances
      async: 600  # Maximum runtime in seconds. Adjust as needed.
      poll: 0  # Fire and continue (never poll)

    - name: Wait for creation to finish
      async_status:
        jid: "{{ item.ansible_job_id }}"
      register: _jobs
      until: _jobs.finished
      delay: 5  # Check every 5 seconds. Adjust as you like.
      retries: 10  # Retry up to 10 times. Adjust as needed.
      with_items: "{{ _create_instances.results }}"

미래의 독자들을 위해 답에 남은 것이 없다면 그 링크가 질문에 대답 할 수 있지만, 이것이 자신의 말 / 예를 들어 문제를 해결하는 데 어떻게 도움이되는지 보여주고 더 자세한 정보를 위해 링크를 남겨 두십시오.
Tensibai

예, A.) 테스트하고 B.) 관련 코드가 여기에 배치 될 때까지 이것을 답변으로 표시 할 수 없습니다. 그럼에도 불구 하고이 방향으로 나를 가리켜 주셔서 감사합니다.
피터 터너

죄송합니다, 그것은 서둘러 :)
webKnjaZ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.