生产级 Ansible 部署全流程-nginx示例
1. 准备机器(示例)
| 主机 | IP | 角色 |
|---|---|---|
| control-node | 192.168.1.100 | Ansible 控制机(你的笔记本或跳板机) |
| web-node | 192.168.1.101 | 被管理节点(部署 Nginx) |
所有机器为 RHEL7/8/9/10或 Ubuntu 20.04+,
2. 在 control-node 上安装 Ansible
2.1安装ansible
全平台Ansible一键安装脚本:Ubuntu/Debian/RHEL全支持-CSDN博客
2.2 在目标机上创建部署用户(deploy)
此步骤需在 每台目标机 上执行(示例:192.168.1.101)
# 登录目标机
ssh root@192.168.1.101# 创建 deploy 用户(必须使用 /bin/bash,Ansible 需要 shell)
useradd -m -s /bin/bash deploy# 设置 deploy 用户密码(临时,用于 ssh-copy-id)
echo "deploy:MySecurePass123" | chpasswd# 赋予 sudo 权限(无需密码)
echo "deploy ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/deploy
chmod 440 /etc/sudoers.d/deploy# (可选但推荐)禁用 root 远程登录 + 禁用密码认证
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd# 退出目标机
exit
2.3跨主机免密码认证
# 切换到普通用户(推荐不要用 root 运行 Ansible)
# 如果控制机尚未创建 deploy 用户,则先创建
useradd -m -s /bin/bash deploy
# 设置本地 deploy 用户密码(仅用于 su 切换,不影响远程)
passwd deploy# 切换到 deploy 用户(后续所有操作在此用户下进行)
su - deploy# 生成 SSH 密钥对(无密码,便于自动化)
# - `-t rsa -b 4096`:使用高强度 RSA 密钥
# - `-N ""`:私钥不设密码
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""# 将公钥复制到目标机(会提示输入第 2 步设置的临时密码)
ssh-copy-id deploy@192.168.1.101# 验证免密登录是否成功(应无需密码直接返回结果)
ssh deploy@192.168.1.101 "whoami && uptime"# (可选)删除目标机 deploy 用户的密码,仅保留密钥认证
# `passwd -d` 删除密码,用户无法用密码登录
ssh deploy@192.168.1.101 "sudo passwd -d deploy"
此后 deploy 用户只能通过密钥登录,且无密码。
3:创建完整的 Ansible 项目目录结构
# 确保当前在 deploy 用户家目录下
cd ~# 使用 brace expansion 一次性创建标准 Ansible 项目结构
# 符合官方推荐布局,便于维护和协作
mkdir -p ansible-proj/{ \configs/group_vars, \configs/env, \playbooks, \roles/prepare/tasks, \roles/prepare/handlers, \roles/nginx/tasks, \roles/nginx/templates, \roles/nginx/handlers, \files, \logs \
}# 进入项目目录
cd ansible-proj
目录说明:
configs/:存放 inventory 和变量playbooks/:顶层编排文件roles/:模块化任务(符合 Ansible 最佳实践)files/:用于存放离线安装包(如 RPM)logs/:Ansible 执行日志
4:创建所有配置文件
4.1 ansible.cfg —— Ansible 全局配置
cat > ansible.cfg <<'EOF'
[defaults]
# 指定 inventory 文件路径
inventory = configs/hosts.ini
# 默认远程用户(避免在 playbook 中硬编码)
remote_user = deploy
# 关闭 SSH 主机密钥检查(自动化场景常用,生产环境可开启)
host_key_checking = False
# 指定 roles 搜索路径
roles_path = roles
# 使用 YAML 格式输出,更易读
stdout_callback = yaml
# 启用任务耗时统计(便于性能分析)
callback_whitelist = profile_tasks
# 记录执行日志(便于审计和排错)
log_path = ./logs/ansible.log[privilege_escalation]
# 默认启用 sudo 提权
become = true
# 使用 sudo 方式提权
become_method = sudo
# 不提示输入 sudo 密码(因已配置 NOPASSWD)
become_ask_pass = false
EOF
4.2 configs/hosts.ini —— 主机清单
cat > configs/hosts.ini <<'EOF'
# 定义 web 主机组(可扩展多台)
[web]
web-01 ansible_host=192.168.1.101# 全局变量(适用于所有主机)
[all:vars]
# 显式指定 Python 解释器路径(避免某些系统默认为 python2)
ansible_python_interpreter=/usr/bin/python3
EOF
4.3 configs/group_vars/all.yml —— 全局默认变量
mkdir -p configs/group_vars
cat > configs/group_vars/all.yml <<'EOF'
# Nginx 默认监听端口(开发/测试用)
nginx_port: 8080
# Nginx worker 连接数
nginx_worker_connections: 1024
EOF
4.4 configs/env/prod.yml —— 生产环境覆盖变量
mkdir -p configs/env
cat > configs/env/prod.yml <<'EOF'
# 生产环境使用标准 80 端口
nginx_port: 80
# 提高连接数以应对高并发
nginx_worker_connections: 2048
EOF
通过
--extra-vars加载此文件,可覆盖默认值,实现多环境部署。
4.5 roles/prepare/tasks/main.yml —— 系统初始化任务
cat > roles/prepare/tasks/main.yml <<'EOF'
---
- name: 安装常用工具(便于调试和运维)package:name:- curl # HTTP 测试- wget # 文件下载- vim # 编辑器- net-tools # ifconfig, netstat 等- rsync # 文件同步state: presenttags: prepare- name: 停止并禁用 firewalld(CentOS 系统)systemd:name: firewalldstate: stoppedenabled: no# 仅在 RedHat 系列系统执行when: ansible_os_family == "RedHat"# 忽略错误(如系统未安装 firewalld)ignore_errors: yes
EOF
4.6 roles/nginx/tasks/main.yml —— Nginx 安装与配置
cat > roles/nginx/tasks/main.yml <<'EOF'
---
- name: 安装 Nginx(Ubuntu/Debian)apt:name: nginxstate: presentupdate_cache: yeswhen: ansible_os_family == "Debian"- name: 安装 Nginx(CentOS/Rocky)yum:name: nginxstate: presentwhen: ansible_os_family == "RedHat"- name: 渲染 Nginx 配置文件(使用 Jinja2 模板)template:src: nginx.conf.j2dest: /etc/nginx/nginx.conf# 配置变更后触发 handler 重启服务notify: restart nginx- name: 启动并启用 Nginx 服务(开机自启)systemd:name: nginxstate: startedenabled: yes
EOF
4.7 roles/nginx/templates/nginx.conf.j2 —— Nginx 模板
cat > roles/nginx/templates/nginx.conf.j2 <<'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;events {worker_connections {{ nginx_worker_connections }};
}http {server {# 动态监听端口(来自变量)listen {{ nginx_port }};location / {root /usr/share/nginx/html;index index.html;}}
}
EOF
使用 Jinja2 模板实现配置参数化,避免硬编码。
4.8 roles/nginx/handlers/main.yml —— 服务重启逻辑
cat > roles/nginx/handlers/main.yml <<'EOF'
---
- name: restart nginxsystemd:name: nginxstate: restarted
EOF
Handler 仅在被
notify触发时执行,避免不必要的服务重启。
4.9 Playbook 文件 —— 编排流程
# 系统初始化 playbook
cat > playbooks/01-prepare.yml <<'EOF'
---
- name: 系统初始化hosts: allroles:- prepare
EOF# Web 服务部署 playbook
cat > playbooks/02-web.yml <<'EOF'
---
- name: 部署 Nginx Web 服务hosts: web# 加载全局变量(也可通过 group_vars 自动加载)vars_files:- ../configs/group_vars/all.ymlroles:- nginx
EOF# 总入口 playbook(组合执行)
cat > playbooks/90-deploy.yml <<'EOF'
---
- import_playbook: 01-prepare.yml
- import_playbook: 02-web.yml
EOF
使用
import_playbook实现模块化编排,便于复用和测试。
5:执行部署
# 创建日志目录(ansible.cfg 中已指定路径)
mkdir -p logs# 测试 Ansible 与目标机连通性
ansible all -m ping# 执行完整部署流程,并加载生产环境变量
ansible-playbook playbooks/90-deploy.yml --extra-vars "@configs/env/prod.yml"
输出为 YAML 格式,清晰显示每个任务状态(ok/changed/failed)。
6:验证结果
# 检查 Nginx 服务状态
ansible web -m systemd -a "name=nginx"# 在目标机本地测试 Nginx 响应
ssh deploy@192.168.1.101 "curl -s http://localhost:80 | head -n 5"# 从控制机访问 Web 服务(验证网络连通性)
curl http://192.168.1.101:80
应返回 Nginx 默认欢迎页 HTML 片段。
7:安全收尾(可选)
# 锁定 deploy 用户密码(彻底禁用密码登录)
# 方法 1:锁定密码(仍可通过密钥登录)
ssh deploy@192.168.1.101 "sudo passwd -l deploy"# 方法 2:设置无效密码(更彻底)
ssh deploy@192.168.1.101 "sudo usermod -p '*' deploy"
此后 deploy 用户 只能通过 SSH 密钥登录,极大提升安全性。
8 最终目录结构验证
# 安装 tree(如未安装)
sudo yum install -y tree || sudo apt install -y tree# 查看项目结构
tree ~/ansible-proj
预期输出:
ansible-proj/
├── ansible.cfg
├── configs/
│ ├── hosts.ini
│ ├── group_vars/
│ │ └── all.yml
│ └── env/
│ └── prod.yml
├── playbooks/
│ ├── 01-prepare.yml
│ ├── 02-web.yml
│ └── 90-deploy.yml
├── roles/
│ ├── prepare/
│ │ └── tasks/main.yml
│ └── nginx/
│ ├── tasks/main.yml
│ ├── templates/nginx.conf.j2
│ └── handlers/main.yml
├── files/
├── logs/
└── (no other files)
9、生产增强建议(可选)
| 能力 | 实现方式 |
|---|---|
| 离线部署 | 将 Nginx RPM/deb 包放入 files/,用 copy + yum install ./xxx.rpm |
| 多环境 | 创建 configs/prod.yml、configs/staging.yml,通过 -e env=prod 加载 |
| Vault 加密 | 敏感变量用 ansible-vault encrypt_string 加密 |
| CI/CD 集成 | 在 Jenkins/GitLab CI 中执行 ansible-playbook |
| 日志记录 | 添加 --log-path ./deploy.log |
10、项目打包(便于分发)
tar -czvf ansible-web-deploy.tar.gz -C ~/ ansible-web-deploy
交付给运维团队后,只需:
tar -xzvf ansible-proj.tar.gz
cd ansible-proj
ansible-playbook playbooks/90-deploy.yml