使用 Ansible 批量部署 Nginx 负载均衡配置文件,最推荐的方式是通过 playbook 结合 template 模块分发渲染后的配置,适合管理 3 台以上服务器且配置需要差异化的场景。
先说结论:Ansible 通过 inventory 分组、template 模板渲染和 playbook 任务编排,可以一次性将 Nginx 负载均衡配置推送到多台后端服务器。为确保安全,必须在推送前备份原配置,并在重启前执行语法检查。
- 适合:管理 3 台以上 Nginx 节点、配置需要按主机差异化、需要频繁更新配置的场景
- 先准备:配置 SSH 免密登录、编写主机清单(使用 ansible_user)、准备包含完整 http 块的 Nginx 配置模板
- 验收:执行 playbook 后检查各节点配置文件内容、Nginx 语法测试、服务状态和端口监听
命令速用版
如果已有 Ansible 环境和主机清单,以下命令可快速完成 Nginx 配置分发和服务重启(生产环境建议先备份):
ansible web_servers -m copy -a "src=/local/loadbalancer.conf dest=/etc/nginx/conf.d/loadbalancer.conf owner=root group=root mode=0644" ansible web_servers -m shell -a "nginx -t" ansible web_servers -m systemd -a "name=nginx enabled=yes state=restarted"
使用 playbook 方式更推荐,可一次性完成安装、配置备份、配置推送、语法检查、启动全流程:
ansible-playbook nginx_lb.yml -i hosts
核心原理
传统运维需要逐台 SSH 登录修改配置,效率低且容易遗漏或出错。Ansible 的核心优势在于通过 inventory 文件定义主机组,用 playbook 描述期望状态,执行时自动对比目标主机当前状态并执行必要操作。template 模块支持 Jinja2 模板语法,可以在配置文件中嵌入变量,实现同一模板适配不同主机(如不同后端服务器地址、端口等)。
Nginx 负载均衡配置通常包含 upstream 定义和 server 块。若直接覆盖主配置文件 /etc/nginx/nginx.conf,必须确保模板包含完整的 events 和 http 块结构,否则 Nginx 无法启动。Ansible 将配置集中管理,变更时只需更新模板或变量文件,重新执行即可同步到所有节点。
分步处理
步骤 1:配置 SSH 免密登录
Ansible 依赖 SSH 协议连接被管理主机,需先配置控制节点到所有目标主机的免密登录:
ssh-keygen -t ed25519 -C "Ansible deploy" ssh-copy-id root@192.168.1.101 ssh-copy-id root@192.168.1.102
验证免密是否成功:ssh root@192.168.1.101 应无需输入密码直接登录。
步骤 2:编写主机清单
编辑/etc/ansible/hosts 或项目目录下的 hosts 文件,按角色分组。注意使用 ansible_user 而非已废弃的 ansible_ssh_user:
[web_servers] 192.168.1.101 ansible_user=admin 192.168.1.102 ansible_user=admin [lb_servers] 192.168.1.10 ansible_port=2222
使用 ansible-inventory `--list` 命令可验证主机分组情况。
步骤 3:准备 Nginx 配置模板
在 playbook 同级目录创建 templates 文件夹。若覆盖主配置文件,必须包含 events 和 http 块;若部署到 conf.d,只需 upstream 和 server 块。以下为覆盖主配置的安全模板示例 templates/nginx.conf.j2:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
upstream backend {
server {{ backend_ip_1 }}:80;
server {{ backend_ip_2 }}:80;
}
server {
listen {{ port }};
server_name {{ server_name }};
location / {
proxy_pass http://backend;
}
}
}template 模块会渲染 vars 定义的变量,在配置文件中可以使用 {{ variable }} 调用。
步骤 4:编写 Playbook
创建 nginx_lb.yml 文件,定义部署任务。包含配置备份、跨系统安装兼容、语法检查等安全措施:
---
- hosts: web_servers
become: true
vars:
port: 80
server_name: example.com
backend_ip_1: 192.168.1.21
backend_ip_2: 192.168.1.22
tasks:
- name: Install nginx (compatible with Ubuntu/CentOS)
package:
name: nginx
state: present
- name: Backup existing nginx.conf
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/nginx.conf.bak.{{ ansible_date_time.epoch }}
remote_src: yes
ignore_errors: yes
- name: Configure nginx
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Check and Restart nginx
- name: Ensure nginx is started
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Check and Restart nginx
block:
- name: Test nginx configuration
command: nginx -t
- name: Restart nginx
service:
name: nginx
state: restarted注意 playbook 中 tasks 后面不要多加空格,否则会导致语法错误。handler 中增加了 nginx -t 检查,确保配置无误后再重启服务。
步骤 5:执行部署
在控制节点执行:
ansible-playbook nginx_lb.yml -i hosts
如需检查语法先执行:ansible-playbook nginx_lb.yml `--syntax-check`
怎么验证是否生效
部署完成后按以下顺序验证:
1. 检查配置文件是否推送成功:登录任意目标主机查看/etc/nginx/nginx.conf 内容,确认变量已正确渲染且包含 events 和 http 块。
2. 测试 Nginx 配置语法:ansible web_servers -m shell -a "nginx -t",返回 syntax is ok 表示配置无误。
3. 检查服务状态:ansible web_servers -m systemd -a "name=nginx state=started" 或 systemctl status nginx。
4. 验证端口监听:ansible web_servers -m shell -a "ss -tulnp | grep 80",确认 Nginx 正在监听指定端口。
5. 实际访问测试:curl -I http://192.168.1.101 应返回 HTTP 响应头,状态码 200 或 301/302 均属正常。
常见坑
1. YUM 仓库未配置:playbook 执行到安装时报错,可能是 epel 仓库未启用。先执行 yum install -y epel-release 或配置官方 Nginx 源后再重试,或使用 package 模块自动适配 apt/yum。
2. 模板变量未定义:template 模块渲染时如果变量不存在会报错,确保 vars 段或 vars_files 中已定义所有模板中使用的变量。
3. 配置文件结构缺失:若覆盖/etc/nginx/nginx.conf,模板必须包含 events 和 http 块,否则 Nginx 无法启动。建议部署前在本地测试模板渲染结果。
4. Handler 未触发:notify 引用的 handler 名称必须与 handlers 段中定义的名称完全一致,包括大小写和空格。
5. 权限问题:copy 或 template 模块推送文件时,确保 dest 路径的父目录存在且目标用户有写入权限,必要时加 become: true 提权。
6. 主机连通性:执行前先用 ansible web_servers -m ping 测试连通性,收到 pong 回应说明 SSH 和 Python 环境正常。
参考来源
- Ansible 实战:5 分钟搞定批量服务器配置 (附常用模块速查表) - 介绍了 copy、yum、systemd、shell 等核心模块用法及主机清单配置
- ansible 批量部署 nginx 负载均衡服务器 - 提供了 nginx.yaml playbook 示例及 template 模块变量渲染说明
- Ansible 批量部署 nginx - 包含主机清单配置、ping 模块测试、批量安装和配置推送步骤
- Ansible 运维自动化实战——批量部署 Nginx - 详解 roles 目录结构、tasks/handlers/templates 组织方式
- Ansible 新手指南 - 如何批量管理 NGINX - 包含 SSH 免密配置、ansible-doc 模块查询方法