Ansible如何实现组内串行跨组并行执行Playbook重启ES集群?
实现组内串行、跨组并行的Elasticsearch集群重启方案
要实现你需要的执行流程,我们可以通过动态生成批次分组+串行执行批次Play的纯Ansible方案来完成,无需拆分多个Playbook,完全适配AAP运行。
核心思路
- 从Inventory中提取
hot/warm/cold三组的主机列表,按索引配对生成批次(同一批次包含每组的一台主机,长度不足的组自动补全剩余节点) - 将每个批次的主机加入临时分组
- 依次对每个临时分组执行重启更新任务:每个分组内的主机并行处理,分组之间串行执行(确保上一批次完成后再启动下一批次)
完整Playbook示例
主Playbook文件(es_cluster_restart.yml)
- name: Generate restart batches and create temporary groups hosts: localhost gather_facts: false vars: # 从Inventory中提取各组主机列表 hot_nodes: "{{ groups['hot'] }}" warm_nodes: "{{ groups['warm'] }}" cold_nodes: "{{ groups['cold'] }}" # 生成批次列表:按索引配对三组主机,过滤空值 restart_batches: >- {{ hot_nodes | zip_longest(warm_nodes, cold_nodes) | map('reject', 'none') | list }} tasks: - name: Add hosts to batch groups add_host: name: "{{ node }}" groups: "batch_{{ batch_idx + 1 }}" loop: "{{ restart_batches | enumerate }}" loop_control: loop_var: batch_item label: "Batch {{ batch_item.0 + 1 }}: {{ batch_item.1 | join(', ') }}" vars: batch_idx: "{{ batch_item.0 }}" batch_hosts: "{{ batch_item.1 }}" # 依次执行每个批次的重启更新任务 - name: Process batch 1 hosts: batch_1 serial: "{{ groups['batch_1'] | length }}" # 并行处理该批次所有主机 tasks: - include_tasks: restart_update_tasks.yml - name: Process batch 2 hosts: batch_2 serial: "{{ groups['batch_2'] | length }}" tasks: - include_tasks: restart_update_tasks.yml - name: Process batch 3 hosts: batch_3 serial: "{{ groups['batch_3'] | length }}" tasks: - include_tasks: restart_update_tasks.yml - name: Process batch 4 hosts: batch_4 serial: "{{ groups['batch_4'] | length }}" tasks: - include_tasks: restart_update_tasks.yml
通用任务文件(restart_update_tasks.yml)
将重复的重启更新逻辑抽离到单独文件,避免代码冗余:
- name: Stop Elasticsearch and related services service: name: "{{ item }}" state: stopped loop: - elasticsearch # 添加你的其他关联服务(如filebeat、logstash等) become: true - name: Apply system updates yum: name: "*" state: latest become: true # 若仅需更新特定包,改为:name: ['elasticsearch', 'your-package'] - name: Start Elasticsearch and related services service: name: "{{ item }}" state: started loop: - elasticsearch # 对应上面的关联服务 become: true - name: Wait for Elasticsearch to stabilize uri: url: "http://{{ ansible_default_ipv4.address }}:9200/_cluster/health" return_content: true register: es_health until: es_health.json.status in ['green', 'yellow'] retries: 20 delay: 10
方案说明
- 动态批次生成:使用
zip_longest将三组主机按索引配对,自动处理各组长度不一致的情况(比如warm组多出来的ew4会单独成为最后一个批次) - 临时分组:通过
add_host模块将每个批次的主机加入临时组,方便后续Play精准定位目标主机 - 并行与串行控制:每个批次Play的
serial参数设为组内主机数量,确保该批次所有主机并行执行;Play之间默认串行,保证上一批次完成后再启动下一批次 - 可维护性:重启更新逻辑抽离到单独任务文件,后续修改只需调整该文件,无需改动主Playbook
注意事项
- 确保Ansible的
forks参数足够(默认值为5,满足当前批次最大3台主机的需求;若后续批次主机数增加,可在ansible.cfg中调整forks值) - 根据实际环境修改服务名称、更新方式(如用
apt替代yum)和Elasticsearch健康检查的URL/端口
内容的提问来源于stack exchange,提问作者Alessandro Valentini
相关产品推荐
相关产品推荐

