在集群规模逐渐扩大后,新增节点通常要完成软件源配置、安全基线、依赖包安装、内核参数调整、应用配置分发、服务注册等多个步骤。手动操作时,重复登录和输入命令不仅耗时,而且容易在不同主机之间产生配置差异。Ansible 使用 SSH 连接目标主机,不需要预装 agent,执行完任务后也不会留下额外进程,非常适合批量初始化集群节点。

一、Ansible 批量部署的核心思路
Ansible 的控制节点会读取 inventory 中定义的主机清单,把任务按照分组和变量渲染后,通过 SSH 分发到目标节点执行。与 shell 脚本相比,Ansible 的模块大多具备幂等性,例如 yum、apt、copy、systemd 等模块会先检查当前状态,只有不满足目标状态时才执行变更。这意味着同一个 Playbook 可以反复执行,已配置好的节点不会因为重复运行而产生副作用。
在集群部署中,通常按照角色划分主机组,例如 control-plane、worker、storage、proxy。组和主机都可以定义变量,变量可以来自 group_vars、host_vars,也可以在 inventory 文件中直接声明。有效的分组策略能让 Playbook 中的 when 条件和模板渲染更清晰,避免为每个节点单独编写任务。
批量执行时的并发度由 forks 参数控制,默认值是 5。对于网络和磁盘性能较好的集群,可以适当提高到 20 或 50,但要避免控制节点 SSH 连接数过高导致资源紧张。任务的执行顺序在单个主机内是串行的,不同主机之间根据 forks 值并行执行。
二、准备 inventory 与目录结构
一个典型的 Ansible 项目目录可以按如下结构组织:inventory 目录保存主机清单,group_vars 保存组变量,roles 目录保存可复用的角色。下面是一份面向三节点小集群的示例,其中 node1 同时作为部署控制节点,node2 和 node3 作为计算节点。
[all:vars] ansible_user=deploy ansible_become=true ansible_become_method=sudo [control] node1 ansible_host=192.168.10.11 [workers] node2 ansible_host=192.168.10.12 node3 ansible_host=192.168.10.13 [cluster:children] control workers
上述 inventory 中 all:vars 定义了所有主机共享的连接参数,ansible_become=true 表示任务默认通过 sudo 提权执行。生产环境建议使用密钥认证,并在控制节点上配置好 SSH config,减少密码交互。如果目标节点 SSH 端口不同,可以用 ansible_port 变量覆盖。
目录结构还可以进一步包含 group_vars/workers.yml、group_vars/control.yml,把不同角色的软件版本、监听端口、节点标签等变量分开维护。这样以后新增角色时,不需要改动 Playbook 主体,只需要添加组变量和 inventory 记录。
三、编写可复用的 Playbook
一个完整的集群部署 Playbook 至少包含基础环境准备、软件安装、配置分发和服务启动四个阶段。为了体现幂等性,每个任务都应优先使用 Ansible 内置模块,而不是直接调用 shell 命令。使用 shell 或 command 模块时,建议通过 creates 或 removes 参数增加判断条件,否则每次执行都会报告 changed。
下面是一个简化版 Playbook,演示如何批量安装依赖、同步配置并启动服务。
---
- name: 部署集群节点基础环境
hosts: cluster
gather_facts: true
tasks:
- name: 安装基础依赖包
ansible.builtin.package:
name:
- vim
- htop
- ntp
- python3
state: present
- name: 开启内核转发
ansible.builtin.sysctl:
name: net.ipv4.ip_forward
value: '1'
state: present
reload: true
- name: 创建集群配置目录
ansible.builtin.file:
path: /etc/myscale
state: directory
owner: root
group: root
mode: '0755'
- name: 分发节点配置文件
ansible.builtin.template:
src: node.conf.j2
dest: /etc/myscale/node.conf
owner: root
group: root
mode: '0644'
notify: restart myscale
handlers:
- name: restart myscale
ansible.builtin.systemd:
name: myscale
state: restarted
enabled: true
上面的 Playbook 中,notify 和 handlers 配合使用,只有配置文件真正发生变更时才会触发服务重启。这样批量执行时,已经拥有相同配置的节点不会重启服务,避免无意义的抖动。对于集群核心进程,频繁重启可能导致选主或数据同步异常,因此这一点在集群场景中很重要。
如果不同角色的节点需要安装不同组件,可以使用 when 条件结合组变量控制任务。例如在 workers 组安装容器运行时,在 control 组安装调度器组件。
- name: 安装容器运行时
ansible.builtin.package:
name: "{{ runtime_package }}"
state: present
when: "'workers' in group_names"
变量 runtime_package 可以在 group_vars/workers.yml 中定义为 containerd 或 docker-ce。使用变量后,同一段任务可以适配不同操作系统或不同版本集群。
四、批量执行与结果校验
准备好 Playbook 后,可以先使用 --check 模式进行预检。check 模式会在不修改目标主机的前提下预测变更,帮助发现变量渲染错误、权限不足或主机不可达等问题。确认无误后,再正式执行。
# 检查模式 ansible-playbook -i inventory/hosts site.yml --check # 正式执行,限制在 workers 组 ansible-playbook -i inventory/hosts site.yml --limit workers -f 20
-f 20 表示同时向 20 台主机分发任务。对于几百台节点的集群,可以逐步提高并发数,但要观察控制节点的 CPU、内存和 SSH 连接状态。如果使用云环境,还需要注意安全组规则是否允许控制节点访问目标节点的 SSH 端口。
执行完成后,可以用 ansible 命令行模块对所有节点做结果校验。例如检查服务状态、查看内核参数、验证配置文件内容。
# 检查集群服务是否运行 ansible cluster -i inventory/hosts -m systemd -a "name=myscale state=started" --become # 查看所有节点的内核转发参数 ansible cluster -i inventory/hosts -m shell -a "sysctl net.ipv4.ip_forward" --become
如果输出中每个主机都显示 SUCCESS,并且返回的服务状态为 active,说明批量部署基本成功。对于需要节点间互相通信的集群,还应继续验证网络连通性、端口监听和集群成员状态,这些可以再编写一个验证 Playbook 统一执行。
五、常见问题与优化建议
批量部署中最常见的问题是 SSH 认证失败和 sudo 权限不足。控制节点使用普通用户连接时,要在 inventory 中正确设置 ansible_become 相关参数,并确保该用户在目标主机上拥有免密 sudo 权限。另一个常见问题是不同主机的 Python 版本不一致。Ansible 需要在目标节点上找到可用的 Python 解释器,可以通过 ansible_python_interpreter 变量指定。
当节点数量较多时,建议使用 roles 组织任务,把公共任务、角色任务和验证任务拆开。roles 的目录结构如下:
roles/
common/
tasks/main.yml
handlers/main.yml
templates/
control/
tasks/main.yml
templates/
workers/
tasks/main.yml
templates/
这种结构让不同角色之间的依赖关系更明确,也方便团队成员分工维护。变量可以放在 roles 对应的 defaults 或 vars 目录中,优先级由 Ansible 的变量合并规则决定。通常 defaults 中的默认值可以被 inventory 和 group_vars 覆盖,适合存放通用的版本号和路径。
为了进一步缩短部署时间,可以在基础镜像中预装一些公共依赖和 Python 环境,这样 Ansible 只需要处理差异部分。对于需要下载大体积软件包的场景,可以配置本地软件源或缓存代理,减少每台节点重复下载带来的带宽压力。批量部署完成后,把 Playbook 纳入版本控制系统,并通过 CI 定期运行检查模式,可以持续发现配置漂移。
总之,Ansible 在批量部署集群节点时的优势在于无代理架构、内置模块幂等性和清晰的任务编排。通过合理的 inventory 分组、变量分层和 roles 组织,团队可以用同一套 Playbook 完成从基础环境到业务服务的初始化。遇到规模增长时,也只需要调整并发参数和优化网络源,无需推翻已有自动化体系。