代码之家  ›  专栏  ›  技术社区  ›  LJS

如何加快包含许多项目的Ansible循环

  •  0
  • LJS  · 技术社区  · 3 年前

    我有一个Ansible Tower剧本,其中包括task1,task1包括task2,task2包括task3,最后task3包括task4。所有这些都有循环。这是可行的,但问题是环境非常大,因此需要几个小时才能完成所有项目(在这种情况下,超过1万个虚拟机——任务2结束)。

    有办法加快速度吗?我知道我可以创建多个作业模板,即每个vCenter创建一个作业模板并允许并发,但我希望只有一个模板,并在可能的情况下并行执行一些任务。

    我看到有一个异步选项可以用于一些任务,然后这个任务可以并行完成,但当我尝试时,我得到了这样的消息:

     ERROR! 'async' is not a valid attribute for a TaskInclude
    

    所以,看起来我无法将async与include_task结合起来。有什么变通办法吗?

    代码如下:

    主要行动手册:

    
    ---
    
        - name: Scheduled job for automatic deletion of old VM snapshots
          hosts: localhost
          gather_facts: true
          connection: local
          collections:
            - community.vmware
          vars_files:
            - vars/vars-vmware-snapshot.yml
          tasks:
          
          - debug: 
              msg: List of vCenters for which old VM snapshots will be deleted "{{ vcenters_list }}"
        
          - name: Loop through all vCenters
            include_tasks: vmware-snapshots-scheduled-delete-task1.yml
            loop: "{{ vcenters_list }}"
            loop_control:
              loop_var: vc_item
    
    

    任务1:

        
          - name: Current item (vCenter) from loop
            debug:
              msg: "{{ vc_item }}"
          
          - name: Gather information about datacenters for the vCenter "{{ vc_item }}"
            community.vmware.vmware_datacenter_info:
              hostname: "{{ vc_item }}"
              username: "{{ vcenter_username }}"
              password: "{{ vcenter_password }}"
              validate_certs: False
            delegate_to: localhost
            register: datacenters_information
        
          - name: List of datacenters for the vCenter "{{ vc_item }}"
            set_fact:
              datacenters_list: "{{datacenters_information.datacenter_info | map(attribute='name')}}"
        
          - name: Loop through "{{ vc_item }}" datacenters
            include_tasks: vmware-snapshots-scheduled-delete-task2.yml
            loop: "{{ datacenters_list }}"
            loop_control:
              loop_var: dc_item
    
    

    任务2:

    
       
          - name: Current item (datacenter) from loop
            debug:
              msg: "{{ dc_item }}"
          
          - name: Gather only registered virtual machines from the current datacenter "{{ dc_item }}" in "{{ vc_item }}"
            community.vmware.vmware_vm_info:
              hostname: "{{ vc_item }}"
              username: "{{ vcenter_username }}"
              password: "{{ vcenter_password }}"
              vm_type: vm
              folder: "/{{ dc_item }}/vm/"
              validate_certs: False
            delegate_to: localhost
            register: vm_information
            ignore_errors: true
              
          - name: Filter just VM names
            set_fact:
              vm_list: "{{ vm_information.virtual_machines | map(attribute='guest_name') }}"
            ignore_errors: true
        
          - name: Loop through VM's for the current datacenter "{{ dc_item }}" in "{{ vc_item }}"
            include_tasks: vmware-snapshots-scheduled-delete-task3.yml
            loop: "{{ vm_list }}"
            loop_control:
              loop_var: vm_item
            ignore_errors: true
    
    

    任务3

    
          - name: Current item (virtual machine) from loop
            debug:
              msg: "{{ vm_item }}"
        
          - name: Remove brackets from vm_item and also convert "%2f" to original "/" if there is "/" in the VM name
            set_fact:
              vm_item2: "{{ vm_item | regex_replace('\\[|\\]', '') | regex_replace('%2f', '/')  }}"
        
          - name: Gather snapshot information for the virtual machine "{{ vm_item2 }}" in "{{ vc_item }}"
            community.vmware.vmware_guest_snapshot_info:
              hostname: "{{ vc_item }}"
              username: "{{ vcenter_username }}"
              password: "{{ vcenter_password }}"
              datacenter: "{{ dc_item }}"
              folder: "/{{ dc_item }}/vm/"
              name: "{{ vm_item2 }}"
              validate_certs: False
            delegate_to: localhost
            register: snapshot_info
                
          - name: Loop through all snapshots for the virtual machine "{{ vm_item2 }}" in "{{ vc_item }}"
            include_tasks: vmware-snapshots-scheduled-delete-task4.yml
            loop: "{{ snapshot_info.guest_snapshots.snapshots }}"
            loop_control:
              loop_var: snapshot_item
            when: 
              - snapshot_info.guest_snapshots | length > 0
    

    知道吗?谢谢

    0 回复  |  直到 3 年前
        1
  •  3
  •   flowerysong    3 年前

    Ansible每次为每个主机执行一个任务,因此并行处理涉及多个内容的任务的最佳方法是将它们实际添加为主机,而不是在localhost上循环。不要将以localhost为目标的单个播放拆分为循环播放的多个任务文件,而是使用多个播放:

    - name: Scheduled job for automatic deletion of old VM snapshots
      hosts: localhost
      gather_facts: true
      vars_files:
        - vars/vars-vmware-snapshot.yml
      tasks:
        - debug:
            msg: List of vCenters for which old VM snapshots will be deleted "{{ vcenters_list }}"
    
        - name: Add vCenters to inventory
          ansible.builtin.add_host:
            name: "{{ item }}"
            groups: vcenter_targets
            vcenter_username: "{{ vcenter_username }}"
            vcenter_password: "{{ vcenter_password }}"
          loop: "{{ vcenters_list }}"
    
    - hosts: vcenter_targets
      gather_facts: false
      tasks:
        - name: Gather information about datacenters for the vCenter
          community.vmware.vmware_datacenter_info:
            hostname: "{{ inventory_hostname }}"
            username: "{{ vcenter_username }}"
            password: "{{ vcenter_password }}"
            validate_certs: false
          delegate_to: localhost
          register: dc_results
    
        - name: Gather registered virtual machines from datacenters
          community.vmware.vmware_vm_info:
            vm_type: vm
            folder: "/{{ item }}/vm/"
            hostname: "{{ inventory_hostname }}"
            username: "{{ vcenter_username }}"
            password: "{{ vcenter_password }}"
            validate_certs: false
          loop: "{{ dc_results.datacenter_information | map(attribute='name') }}"
          delegate_to: localhost
          register: vm_results
    
        - name: Add virtual machines to inventory
          ansible.builtin.add_host:
            name: "{{ item.1.guest_name | replace('[', '') | replace(']', '') | replace('%2f', '/') }} ({{ item.1.uuid }})"
            uuid: "{{ item.1.uuid }}"
            groups: vm_targets
            vcenter_username: "{{ vcenter_username }}"
            vcenter_password: "{{ vcenter_password }}"
            vcenter_hostname: "{{ inventory_hostname }}"
            vcenter_datacenter: "{{ item.0.item }}"
          loop: "{{ vm_results.results | subelements('virtual_machines') }}"
          loop_control:
            label: "{{ item.0.item }}: {{ item.1.guest_name }}"
    
    - hosts: vm_targets
      gather_facts: false
      tasks:
        - name: Gather snapshot information
          community.vmware.vmware_guest_snapshot_info:
            uuid: "{{ uuid }}"
            datacenter: "{{ vcenter_datacenter }}"
            hostname: "{{ vcenter_hostname }}"
            username: "{{ vcenter_username }}"
            password: "{{ vcenter_password }}"
            validate_certs: false
          delegate_to: localhost
          register: snapshot_results
    
        - name: Loop through snapshots
          ansible.builtin.include_tasks: vmware-snapshots-scheduled-delete-task4.yml
          loop: "{{ snapshot_results.guest_snapshots.snapshots }}"
          loop_control:
            loop_var: snapshot_item
    

    请注意,我没有vCenter环境可供测试,因此此代码可能包含一些小错误。不过,这应该足以说明这一原则。