怎么使用 Ansible 批量部署 Nginx 负载均衡配置文件

文章导读
使用 Ansible 批量部署 Nginx 负载均衡配置文件,最推荐的方式是通过 playbook 结合 template 模块分发渲染后的配置,适合管理 3 台以上服务器且配置需要差异化的场景。
📋 目录
  1. 命令速用版
  2. 核心原理
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

使用 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 批量部署 Nginx 负载均衡配置文件
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 模块查询方法