Có cách nào để chạy các vòng lặp with_items song song trong Ansible không?


12

Tôi đang chạy Ansible 2.2, nhưng có thể nâng cấp nếu nó giúp.

Tôi đã thấy điều này và khá phấn khích, nhưng dường như nó không có trong phiên bản (hoặc bất kỳ) tài liệu Ansible này.

Vấn đề tôi đang cố gắng giải quyết là tôi đã có 1000 người dùng mà tôi cần quản lý trên hộp Centos.

Phải mất khá nhiều thời gian để chạy nhiệm vụ này một cách thanh thản. Và thậm chí khó chịu hơn, mọi thứ hiển thị như đã thay đổi vì lệnh "hết hạn" trên mô-đun người dùng luôn đánh dấu điều đã thay đổi.

điều này cũng có vẻ đầy hứa hẹn, nhưng phải mất cùng thời gian để chạy từng lệnh trong vòng lặp with_items và không đi nhanh hơn nữa (tôi không bao giờ bận tâm chờ đợi đủ lâu để đi đến cuối cùng).

Bỏ qua các tác vụ nhanh chóng (nhanh hơn rất nhiều so với Ansible 2.0), nếu tôi không thể tìm ra cách thực hiện công việc này song song, tôi nghĩ tôi sẽ quay lại và tìm cách bỏ qua các nhiệm vụ vô nghĩa và nếu tất cả nếu không, tôi sẽ viết mô-đun của riêng tôi. Nhưng có vẻ như tôi sẽ có thể làm tất cả những điều này nhanh hơn trong Ansible.


Đây là những gì tôi muốn chạy song song, host_authorizationslà một danh sách tên người dùng và dữ liệu khác.

  - 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

Vui lòng cung cấp một đoạn mã. Nếu không thì thật khó để giúp đỡ.
030

@ 030 có một đoạn trích, tôi đoán nó sẽ giúp một chút cho bối cảnh. Về mặt khái niệm, tôi quan tâm nhiều hơn nếu thực sự có một cách để chạy các tác vụ (trong một vòng lặp) song song trên cùng một máy chủ. Tôi biết tôi có thể làm rất nhiều việc riêng lẻ với async, nhưng không quá nhiều với with_items.
Peter Turner

Vì vậy, về cơ bản nếu 1000 người dùng phải được tạo thì nó sẽ được hoàn thành nhanh như tạo chỉ một người dùng. Thật thú vị, tại sao không sử dụng một cái gì đó như LDAP?
030

1
Nghiêm túc mà nói, bạn đang hướng đến một con đường đau khổ, tôi không nghĩ có ai xử lý hơn một chục tài khoản với cơ sở tài khoản địa phương, ngay khi số lượng người dùng tăng lên, tôi cho rằng mọi người đều chuyển sang một hệ thống kế toán tập trung, thông thường một số phụ trợ ldap (có thể là thư mục hoạt động) và sau đó đặt thời gian hết hạn và khóa chung làm thuộc tính của cơ sở trung tâm này, sau đó sử dụng những thứ như sss_ssh_ trái phép để cho máy chủ ssh lấy các khóa được ủy quyền từ cơ sở trung tâm này.
Tensibai

2
Tôi không đồng ý đây là những gì ansible dành cho (gợi ý là nó không thực hiện việc tạo / quản lý người dùng hàng loạt). Tôi đồng ý rằng các tài khoản không nên được quản lý trên cơ sở tài khoản địa phương với khối lượng lớn (thực tế chúng không phải là tài khoản của con người không liên quan đến vấn đề này)
Tensibai

Câu trả lời:


13

Như @webKnja đã đề cập, điều này là có thể với asyncchế độ. Gần đây tôi đã tự khám phá ra nó và học được rằng bạn có thể sử dụng nó theo 3 cách khác nhau tùy theo nhu cầu của bạn.

  1. Thực hiện và thăm dò kết quả, chú ý poll:5, Điều này sẽ thăm dò kết quả cứ sau 5 giây. Bạn có thể tiết kiệm thời gian với phương pháp này.

    - 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. Cháy và quên đi poll: 0 , Đây là tùy chọn rất nhanh vì Ansible chỉ bắn ra những nhiệm vụ đó. Mặt trái là chúng ta không biết kết quả của nhiệm vụ là gì changed: True/False. Tất nhiên đó là nhược điểm nếu bạn quan tâm đến phản hồi;).

    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. Cháy và quên vớiasync_status , cú pháp cho nhiệm vụ giống như ví dụ 2 dù nó sẽ yêu cầu nhiệm vụ bổ sung async_status. Đây là mục ưa thích của tôi vì nó tương đối nhanh (nhanh hơn bình thường hoặc vòng lặp thông thường execute and poll) và cho phép bạn nắm bắt phản hồi mặc dù sẽ cần phải xử lý mới registercho bạn async_task.

    retries: 20 - bao nhiêu lần thử trước khi thất bại.

    delay: 2 - có bao nhiêu giây để chờ giữa các cuộc thăm dò.

    - 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}}"
    

Một lời cảnh báo , tùy thuộc vào nhiệm vụ yo có thể không thể sử dụng asynctùy chọn. Tôi đã có các ví dụ khi tôi tương tác với hệ thống không thể xử lý nhiều yêu cầu cho cùng một tài nguyên. Tôi thấy asynctùy chọn hoạt động tốt nhất nếu tôi phải thực hiện cùng một nhiệm vụ trên nhiều máy chủ. Đó là nơi tôi có thể "tiết kiệm" nhiều thời gian nhất.

Vì bạn đã đăng liên kết đến tài liệu Ansible trong câu hỏi tôi sẽ không làm điều đó.


@chicks bạn có thể muốn thay đổi pollgiá trị thành 0 trong ví dụ 3. Đây là một lời giải thích tuyệt vời !! Thnx.
Debanjan Basu

@DebanjanBasu Bất cứ ai cũng có thể thực hiện các chỉnh sửa được đề xuất. Tôi có thể là người phê duyệt nó trong hàng đợi đánh giá, nhưng bạn sẽ nhận được tín dụng cho việc chỉnh sửa.
gà con

Đáng buồn thay, một nhân vật không được phép! :(
Debanjan Basu

2
Lựa chọn 3 hoạt động tuyệt vời, cảm ơn! Một bình luận mặc dù: như ít nhất Ansible 2.8, async_statusđòi hỏi jid, không id.
EdwardTeach

4

Để trả lời câu hỏi của bạn: Không, hiện tại Ansible không thể chạy các vòng lặp song song.

Tôi sẽ sử dụng newusersthay thế, được tạo ra để tạo người dùng số lượng lớn. Tạo một tệp có tất cả người dùng trong đó, sao chép nó vào máy chủ và chạy newusers /path/to/user/listtrong một commandtác vụ.


3

Có thể đạt được điều này bằng cách sử dụng asyncchế độ. Vui lòng tìm một số tài liệu tham khảo cho cách làm điều này dưới đây.

Tham chiếu:

---

- 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 }}"

Mặc dù các liên kết đó có thể trả lời câu hỏi nếu chúng phá vỡ không còn gì trong câu trả lời của bạn cho các độc giả tương lai, vui lòng thử trình bày cách điều này sẽ giúp giải quyết vấn đề bằng các từ / ví dụ của riêng bạn và chỉ để lại các liên kết để biết thêm thông tin chi tiết.
Tensibai

vâng, tôi không thể đánh dấu đây là câu trả lời cho đến khi A.) Tôi kiểm tra nó và B.) mã có liên quan được đặt ở đây. Nhưng cảm ơn bạn đã chỉ cho tôi theo hướng này tuy nhiên.
Peter Turner

Xin lỗi, tôi đã vội vàng :)
webKnjaZ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.