1. 项目概述
在现代化企业IT基础设施管理中,自动化部署已经成为提升运维效率的关键手段。今天要分享的是一个基于Ansible的Web服务集群自动化部署方案,实现Nginx+PHP+MySQL的完整服务栈部署。这个方案在我们电商平台的灰度发布环境中已经稳定运行两年多,累计完成超过300次零停机部署。
相比传统手动部署方式,这个Playbook将8小时的人工操作压缩到15分钟自动完成,并且保证了每次部署的环境一致性。特别适合需要频繁更新代码的中大型Web项目,也适用于需要快速搭建标准化开发环境的团队。
2. 架构设计与组件选型
2.1 整体架构规划
我们的目标架构包含以下核心组件:
- Nginx 1.18 作为前端负载均衡和静态资源服务器
- PHP 7.4-FPM 运行动态PHP代码
- MySQL 8.0 作为后端数据库
- Redis 6.2 用于会话缓存
所有服务采用分布式部署,通过Ansible实现配置的统一管理和批量执行。架构设计考虑了横向扩展能力,每个组件都可以通过修改inventory文件轻松扩容。
2.2 技术选型考量
选择Ansible作为自动化工具主要基于以下因素:
- 无代理架构:不需要在目标服务器安装额外客户端
- YAML语法:Playbook可读性强,易于版本控制
- 幂等性:相同Playbook多次执行结果一致
- 丰富的模块库:超过750个内置模块满足各种运维需求
重要提示:生产环境建议使用Ansible 2.9+版本,这个版本系列在稳定性与企业级功能支持方面表现最佳。
3. 环境准备与基础配置
3.1 控制节点配置
控制节点需要满足以下条件:
- Python 3.6+
- Ansible 2.9+
- sshpass工具(用于密码认证)
安装命令示例:
bash复制# Ubuntu/Debian
sudo apt update
sudo apt install -y python3-pip sshpass
pip3 install ansible==2.9.27
# CentOS/RHEL
sudo yum install -y python3-pip sshpass
pip3 install ansible==2.9.27
3.2 目标节点要求
所有被管理节点需要:
- 开启SSH访问
- 配置sudo权限
- 安装Python解释器
可以通过以下Playbook片段批量验证节点状态:
yaml复制- name: Verify node prerequisites
hosts: all
tasks:
- name: Check Python availability
raw: which python3 || which python
register: python_interpreter
changed_when: false
- name: Install Python if missing
raw: test -e /etc/redhat-release && yum install -y python3 || apt-get install -y python3
when: python_interpreter.stdout == ""
4. Playbook核心实现
4.1 目录结构设计
规范的目录结构是维护大型Playbook的基础:
code复制web-cluster/
├── inventories/
│ ├── production
│ └── staging
├── group_vars/
│ ├── all.yml
│ ├── webservers.yml
│ └── dbservers.yml
├── roles/
│ ├── nginx
│ ├── php
│ ├── mysql
│ └── common
└── site.yml
4.2 Nginx角色实现
nginx/tasks/main.yml关键配置:
yaml复制- name: Install Nginx
apt:
name: nginx
state: present
when: ansible_os_family == 'Debian'
- name: Configure nginx
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
validate: 'nginx -t -c %s'
notify: restart nginx
- name: Enable site configuration
file:
src: "/etc/nginx/sites-available/{{ domain }}"
dest: "/etc/nginx/sites-enabled/{{ domain }}"
state: link
对应的Jinja2模板(nginx.conf.j2)需要包含动态内容:
jinja2复制worker_processes {{ ansible_processor_vcpus }};
events {
worker_connections {{ worker_connections }};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 动态生成upstream配置
upstream php_servers {
{% for server in groups['php_servers'] %}
server {{ hostvars[server].ansible_host }}:9000;
{% endfor %}
}
}
4.3 PHP-FPM优化配置
php/templates/www.conf.j2关键优化参数:
ini复制[www]
listen = 0.0.0.0:9000
pm = dynamic
pm.max_children = {{ php_max_children }}
pm.start_servers = {{ ansible_processor_vcpus * 4 }}
pm.min_spare_servers = {{ ansible_processor_vcpus * 2 }}
pm.max_spare_servers = {{ ansible_processor_vcpus * 6 }}
经验值:pm.max_children = (可用内存 - 系统保留) / 单个PHP进程内存占用
4.4 MySQL安全加固
mysql/tasks/secure.yml包含的重要安全措施:
yaml复制- name: Remove anonymous users
mysql_user:
name: ''
host_all: yes
state: absent
login_user: root
login_password: "{{ mysql_root_password }}"
- name: Remove test database
mysql_db:
name: test
state: absent
login_user: root
login_password: "{{ mysql_root_password }}"
- name: Set root password
mysql_user:
name: root
host: "{{ item }}"
password: "{{ mysql_root_password }}"
priv: "*.*:ALL,GRANT"
with_items:
- 127.0.0.1
- ::1
- localhost
5. 部署流程与执行策略
5.1 分阶段执行策略
建议采用分阶段执行降低风险:
bash复制# 先执行基础配置
ansible-playbook -i inventories/production site.yml --tags "common"
# 验证基础服务
ansible-playbook -i inventories/production site.yml --tags "nginx,php" --check
# 最后执行数据库变更
ansible-playbook -i inventories/production site.yml --tags "mysql" --extra-vars "confirm_destructive=yes"
5.2 零停机部署技巧
实现零停机的关键点:
- Nginx滚动重启:
yaml复制- name: Graceful nginx restart
command: kill -HUP `cat /var/run/nginx.pid`
when: nginx_restart_required
- PHP-FPM平滑重载:
yaml复制- name: Reload PHP-FPM
command: /etc/init.d/php7.4-fpm reload
- MySQL主从切换(需要额外配置复制角色)
6. 常见问题排查
6.1 连接超时问题
典型表现:Nginx 502 Bad Gateway
排查步骤:
- 检查PHP-FPM监听端口
bash复制netstat -tulnp | grep 9000
- 验证SELinux状态
bash复制getenforce
# 临时禁用
setenforce 0
- 检查防火墙规则
bash复制iptables -L -n
6.2 性能调优参数
关键性能参数参考值(基于8核16G服务器):
| 组件 | 参数 | 建议值 |
|---|---|---|
| Nginx | worker_connections | 4096 |
| PHP-FPM | pm.max_children | 120 |
| MySQL | innodb_buffer_pool_size | 8G |
| MySQL | max_connections | 300 |
6.3 配置验证技巧
在应用配置前进行语法检查:
yaml复制- name: Validate nginx config
command: nginx -t
register: nginx_test
changed_when: false
- name: Fail if config invalid
fail:
msg: "Invalid nginx configuration"
when: nginx_test.rc != 0
7. 监控与维护
7.1 基础监控配置
建议部署以下监控项:
- Nginx状态监控:
yaml复制- name: Enable nginx status
lineinfile:
path: /etc/nginx/nginx.conf
insertafter: 'http {'
line: ' server { listen 127.0.0.1:8080; location /nginx_status { stub_status; } }'
- PHP-FPM状态页:
ini复制pm.status_path = /fpm_status
- MySQL监控用户:
sql复制GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'%' IDENTIFIED BY 'secure_password';
7.2 日志收集方案
集中化日志收集配置示例:
yaml复制- name: Configure rsyslog
template:
src: templates/rsyslog.conf.j2
dest: /etc/rsyslog.conf
notify: restart rsyslog
- name: Install filebeat
apt:
name: filebeat
state: present
- name: Configure filebeat
copy:
src: files/filebeat.yml
dest: /etc/filebeat/filebeat.yml
这个Playbook经过多次迭代已经成为一个成熟的Web服务部署方案。在实际使用中,建议根据具体业务需求调整以下方面:
- 安全组配置(特别是数据库访问控制)
- 监控告警阈值
- 备份策略(尤其是数据库备份频率)
- 自定义应用的部署流程
对于需要更高可用性的场景,可以考虑增加Keepalived实现VIP漂移,或者使用Galera Cluster实现MySQL多主复制。这些扩展都可以通过Ansible Role方便地集成到现有方案中。