AIGC标识 ansible批量节点执行操作

结论

Ansible 批量节点执行的核心是 "控制端 + SSH + 模块" 的 agentless 模型:控制端无需在目标节点安装任何 agent,只要控制端能 SSH 登录节点,就可以通过一条命令(ad-hoc)或一个剧本(playbook)同时操作 Inventory 清单里的成百上千台机器。批量执行有两条主路径:

  • ad-hoc 命令(ansible):适合一次性、简单的批量操作,如批量 ping、批量执行命令、批量拷贝文件、批量重启服务;
  • Playbook 剧本(ansible-playbook):适合多步骤、可复用、带条件判断与回滚逻辑的批量编排,如批量下发配置并重启、批量巡检并汇总。

批量执行的三个关键要素:Inventory(对哪些节点执行)、模块(执行什么操作)、forks / serial(多大并发、如何滚动)。日常批量操作优先用 ad-hoc + 常用模块,复杂的编排才需要写 playbook。

Ansible 批量执行架构

分析环境与版本

本文基于 ansible community package 14.x(ansible-core 2.21.x,2026 年 9 月发布) 编写,示例命令在 Rocky Linux / CentOS 7+ 控制端验证,兼容 ansible-core 2.13 及以上版本。官方支持矩阵要点:

  • 控制端:Python 3.12 ~ 3.14(ansible-core 2.21);旧版本要求更宽松(如 2.15 控制端 Python 3.9+);
  • 被管节点:Python 3.9 ~ 3.14(ansible-core 2.21),节点无需安装 Ansible;
  • 传输协议:SSH(默认端口 22),支持密钥认证与 sudo 提权(become)。

一、批量执行原理

一次批量操作在底层是这样发生的:

  1. 控制端读取 Inventory 清单,解析出所有目标主机与分组;
  2. 对每个目标主机建立 SSH 连接(默认并发 5 个,可用 forks 调整);
  3. 把要执行的 模块(一个 Python 脚本)连同参数打包,上传到节点临时目录;
  4. 节点端用 Python 解释器执行模块,把结果序列化为 JSON;
  5. 控制端回收各节点结果,汇总为 ok / changed / failed 统计。

因此批量执行能否成功,取决于三件事:SSH 能否连上(免密或密码)、节点是否有 Python、模块是否支持该系统的包管理器。这也是排查批量失败时的第一思路。

二、安装与前置条件

控制端安装(任选其一):

# 完整社区版(含常用 collection,推荐)
pip install ansible

# 仅核心(模块较少,按需装 collection)
pip install ansible-core

验证版本:

ansible --version
# ansible [core 2.21.4]
#   config file = /etc/ansible/ansible.cfg

安装完成后生成 SSH 密钥并分发到节点(批量执行的前提,只需一次):

ssh-keygen -t ed25519            # 生成密钥,一路回车
ssh-copy-id root@10.0.0.11       # 逐个节点分发公钥
ssh-copy-id root@10.0.0.12

三、Inventory:告诉 Ansible 操作哪些节点

默认清单文件是 /etc/ansible/hosts,更常用的做法是用 -i 指定自己的清单文件。支持 INI 与 YAML 两种格式。

INI 格式示例(hosts.ini):

[web]
10.0.0.11
10.0.0.12 ansible_host=10.0.0.12 ansible_user=root

[db]
10.0.0.21
10.0.0.22

[mysql:children]
db

[all:vars]
ansible_ssh_private_key_file=/root/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3

要点:

  • [web]、[db] 是主机组,执行时可以只针对某个组;
  • [mysql:children] 表示子组继承(db 组属于 mysql 组);
  • [all:vars] 定义作用于所有主机的变量;
  • 支持范围简写:10.0.0.[11:20] 表示 11~20;
  • ansible_user、ansible_port、ansible_ssh_private_key_file 可写在主机或组变量里,覆盖默认 SSH 连接参数;
  • 大规模集群可使用动态 Inventory(从云平台 API、CMDB 拉取),本质是输出 JSON 清单的脚本。

验证清单与连通性:

ansible -i hosts.ini all --list-hosts          # 列出所有主机
ansible -i hosts.ini all -m ping               # 批量连通性测试

四、SSH 免密与 ansible.cfg

批量执行最怕每台机器都输密码。除了 ssh-copy-id,还可以在 ansible.cfg 统一配置。配置文件查找顺序:当前目录 ansible.cfg > ~/.ansible.cfg > /etc/ansible/ansible.cfg。

[defaults]
inventory = ./hosts.ini        # 默认清单
forks = 20                     # 默认并发数(默认 5)
host_key_checking = False      # 首次连接不提示确认指纹
timeout = 30                   # SSH 连接超时(秒)
interpreter_python = auto_silent   # 节点自动探测 Python,抑制告警
become = True                  # 默认提权
become_method = sudo

密码方式接入(不推荐用于生产,密码会明文出现在命令或文件里):

ansible all -m ping -u root -k      # -k 交互输入 SSH 密码

需要 sudo 密码时:

ansible all -m command -a "id" -b -K     # -b 提权,-K 交互输入 sudo 密码

五、ad-hoc 批量执行(日常主力)

通用语法:

ansible <主机组或模式> -m <模块> -a "<模块参数>"

常用参数:

参数 作用
-i <file> 指定 Inventory 文件
--limit <hosts> 只对部分主机执行(如 --limit 10.0.0.11)
-f / --forks N 并发数(默认 5)
-b / --become 提权执行(sudo)
-K / --ask-become-pass 交互输入 sudo 密码
-u <user> 指定 SSH 用户
-k 交互输入 SSH 密码
-v / -vvv 输出详细信息(排错用)
--check 演习模式,不真正改动
--list-hosts 列出将执行的主机

常用模块一览

模块 用途 示例
ping 连通性测试 -m ping
command 执行命令(不支持管道/重定向/变量) -m command -a "uptime"
shell 执行命令(支持管道等,注意注入风险) `-m shell -a "df -h
script 把控制端本地脚本分发到节点执行 -m script -a "/opt/check_disk.sh"
copy 批量拷贝文件 -m copy -a "src=/tmp/a.conf dest=/etc/a.conf mode=0644"
template 用模板渲染后下发(支持变量) -m template -a "src=a.j2 dest=/etc/a.conf"
yum / apt 批量安装/卸载软件包 -m yum -a "name=htop state=present"
systemd / service 批量启停服务 -m systemd -a "name=nginx state=restarted"
file 批量创建目录/文件、改权限 -m file -a "path=/data state=directory mode=0755"
lineinfile 批量修改配置文件行 -m lineinfile -a "path=/etc/hosts line='10.0.0.5 node5'"
cron 批量添加定时任务 -m cron -a "name='daily backup' minute=0 hour=2 job='/backup.sh'"
user 批量管理用户 -m user -a "name=ops state=present groups=wheel"
setup 批量采集节点系统信息(facts) -m setup
gather_facts playbook 里采集 facts 用 见下文示例

实战场景

1. 批量连通性与主机信息

ansible web -m ping
ansible web -m setup -a "filter=ansible_distribution*"   # 只看发行版信息

2. 批量执行命令

# 不支持管道
ansible all -m command -a "uptime"
# 支持管道/重定向
ansible all -m shell -a "uptime && free -h | head -3"

3. 批量执行本地脚本(最常用)

把控制端上的脚本分发到所有节点并执行,脚本输出会被收集回来:

ansible all -m script -a "/opt/ops/check_disk.sh"
ansible all -m script -a "/opt/ops/deploy.sh --env=prod" -b

4. 批量下发配置文件

ansible all -m copy -a "src=/opt/ops/nginx.conf dest=/etc/nginx/nginx.conf mode=0644 backup=yes" -b

5. 批量安装软件

ansible all -m yum -a "name=htop,iftop state=present" -b
ansible db -m yum -a "name=mysql-server state=absent" -b    # 卸载

6. 批量重启服务(升级后的标准操作)

ansible web -m systemd -a "name=nginx state=restarted enabled=yes daemon_reload=yes" -b

7. 批量加定时任务

ansible all -m cron -a "name='clean tmp' minute=30 hour=3 job='/usr/bin/find /tmp -type f -mtime +7 -delete'"

六、Playbook 批量执行(可复用编排)

当操作超过一条命令、需要条件判断或多步骤时,写 playbook。示例:批量下发 nginx 配置并重启(只对配置变更的机器重启)。

deploy-nginx.yml:

---
- name: 批量部署 nginx 配置
  hosts: web
  become: true
  vars:
    nginx_port: 8080
  tasks:
    - name: 下发配置文件(模板)
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        mode: '0644'
      notify: restart nginx          # 只有文件变化才触发 handler

    - name: 校验配置
      ansible.builtin.command: nginx -t
      register: check_result
      failed_when: "'successful' not in check_result.stdout"

    - name: 打印校验结果
      ansible.builtin.debug:
        msg: "{{ check_result.stdout }}"

  handlers:
    - name: restart nginx
      ansible.builtin.systemd:
        name: nginx
        state: restarted

执行与校验:

ansible-playbook deploy-nginx.yml --syntax-check    # 语法检查
ansible-playbook deploy-nginx.yml --check           # 演习模式
ansible-playbook deploy-nginx.yml --diff            # 显示文件差异
ansible-playbook deploy-nginx.yml --limit 10.0.0.11 # 先单台验证
ansible-playbook deploy-nginx.yml -b -K             # 正式执行(提权)

Playbook 常用控制项:

tasks:
  - name: 循环安装多个包
    ansible.builtin.yum:
      name: "{{ item }}"
      state: present
    loop:
      - htop
      - iftop
      - jq

  - name: 条件执行(仅当文件存在)
    ansible.builtin.command: cat /etc/redhat-release
    when: ansible_os_family == "RedHat"

  - name: 单台失败不中断其余节点
    ansible.builtin.command: /opt/check.sh
    ignore_errors: true

  - name: 按标签选择性执行
    ansible.builtin.systemd:
      name: nginx
      state: restarted
    tags: [restart]

对应命令:ansible-playbook play.yml --tags restart、--tags "restart,config"、--skip-tags restart。

批量巡检示例(采集 facts 并输出摘要):

---
- name: 批量巡检
  hosts: all
  gather_facts: true
  tasks:
    - name: 汇总关键信息
      ansible.builtin.debug:
        msg: "{{ inventory_hostname }} | {{ ansible_distribution }} {{ ansible_distribution_major_version }} | CPU {{ ansible_processor_cores }}c | Mem {{ ansible_memtotal_mb }}MB | IP {{ ansible_default_ipv4.address }}"

执行结果会在控制端逐台打印,配合 register + debug 即可做到"批量执行 + 结果汇总"。

七、并发、分批与滚动

  • forks:ad-hoc 与 playbook 的全局并发。forks = 20 表示同时向 20 台节点发起连接。并发越大,控制端与网络压力越大,按节点规模和操作类型权衡;
  • serial:playbook 中按比例或数量分批执行,适合滚动发布:
- name: 滚动重启
  hosts: web
  serial: 2          # 每批 2 台;也支持 "30%" 或 [1, 3, "50%"]
  become: true
  tasks:
    - name: 重启服务
      ansible.builtin.systemd:
        name: app
        state: restarted
  • throttle:限制单个 task 的并发(如只允许同时重启 5 台),与 serial 配合用于避免雪崩;
  • --limit:临时只操作部分主机,常用于灰度验证后全量。

八、结果查看与常见问题

执行结束后控制端会输出统计:ok=5 changed=3 unreachable=1 failed=0。unreachable 是连接不上,failed 是执行出错,两者都要单独排查。

常见问题与对策:

报错 / 现象 原因 对策
UNREACHABLE! ... Failed to connect to the host via ssh 免密未配 / 端口不通 / 超时 ssh-copy-id 重新分发公钥;检查 ansible_port、timeout
The module failed to execute correctly 节点没有可用的 Python 安装 python3;或设置 ansible_python_interpreter=/usr/bin/python3
[WARNING]: Platform linux ... uses discovered Python interpreter 解释器自动探测告警 ansible.cfg 设 interpreter_python = auto_silent 或显式指定
sudo: a password is required 提权需要密码 -K 交互输入,或配置 NOPASSWD,或 become_user=root become_method=sudo
Host key verification failed 节点指纹变化/未信任 host_key_checking = False(内网可信环境)或先 ssh-keyscan 录入
command 模块里管道不生效 command 不支持 shell 特性 改用 shell 模块
中文乱码 / 编码告警 节点 locale 非 UTF-8 节点设置 LANG=en_US.UTF-8;模块输出一般不影响执行
包管理器报 No package ... available 模块与系统不符 确认用 yum(RHEL 系)/ apt(Debian 系)对应模块

排错三连:-v(第一层)、-vvv(看到 SSH 实际命令)、--check(确认改动范围)。

快速参考

需求 命令
连通性测试 ansible all -m ping
批量执行命令 ansible web -m command -a "uptime"
批量执行本地脚本 ansible all -m script -a "/opt/ops/check.sh"
批量拷贝文件 ansible all -m copy -a "src=x dest=y mode=0644"
批量安装软件 ansible all -m yum -a "name=htop state=present" -b
批量重启服务 ansible all -m systemd -a "name=nginx state=restarted" -b
批量加定时任务 ansible all -m cron -a "name='x' minute=0 hour=2 job='/x.sh'"
只操作部分主机 加 --limit 10.0.0.11
提高并发 -f 20 或 ansible.cfg 设 forks=20
演习不生效 加 --check
跑剧本 ansible-playbook deploy.yml -b

posted on 2026-09-25 21:50  王景迁  阅读(8)  评论(0)    收藏  举报

导航