Orange的运维学习日记--46.Ansible进阶之LNMP部署最佳实践
Orange的运维学习日记–46.Ansible进阶之LNMP部署最佳实践
文章目录
- Orange的运维学习日记--46.Ansible进阶之LNMP部署最佳实践
- 环境与前提
- 部署 MariaDB 数据库
- 初始化应用数据库与用户
- 部署 Nginx Web 服务器
- 安装与配置 PHP 环境
- 部署 WordPress 应用
- 后续验证与扩展
- 常见错误与排查
- 拼写错误
- 格式错误
- MySQL host 问题
- 模块依赖缺失
- 权限与 SELinux 问题
- 防火墙与端口访问
- 日志排查
- 防火墙与端口访问
- 日志排查
本方案基于 Ansible Playbook,实现 CentOS 7 环境下一键部署 WordPress 所需的 MariaDB、Nginx、PHP 及应用程序,并完成基础安全清理与配置
通过分段 Play 对应不同组件职责,让运维流程清晰可控且具备重复执行的幂等性
环境与前提
所有 Play 均针对主机组 controller,确保目标节点已安装 SSH 并可通过 Ansible 控制机访问
需要提前在控制机目录下准备 inventory 文件,将 controller 定义为目标主机
Play 中涉及的变量如下,建议使用 Vault 加密管理
mysql_root_password: "YourRootPass" # MariaDB root 密码
app_user : "webapp_user" # 应用数据库访问用户
app_password : "YourAppPass" # 应用数据库用户密码
app_priv : "webapp_db.*:ALL" # 授权字符串
db_name : "webapp_db" # 应用数据库名
blog_vhost : "blog.example.com" # 网站域名
部署 MariaDB 数据库
此 Play 负责安装 MariaDB、启动服务、设置 root 密码、删除默认匿名用户和 test 数据库,确保数据库实例满足生产安全要求
- name: deploy maridbhosts: controllertasks:- name: install mariadbyum:name:- mariadb-server- python2-PyMySQL # 支持 Ansible mysql 模块state: present- name: enableservice:name : mariadbstate : startedenabled: yes- name: set root@localhost passwordshell: mysqladmin password {{ mysql_root_password }}ignore_errors: yes # 首次运行可能为空密码- name: set root passwordmysql_user:name : rootpassword : "{{ mysql_root_password }}"host : "{{ item }}"state : presentlogin_user : rootlogin_password: "{{ mysql_root_password }}"with_items:- "{{ ansible_fqdn }}"- 127.0.0.1- ::1- name: delete user anonymousmysql_user:name : ""host_all : yesstate : absentlogin_user : rootlogin_password: "{{ mysql_root_password }}"- name: delete database testmysql_db:name : teststate : absentlogin_user : rootlogin_password: "{{ mysql_root_password }}"
安装时附带 python2-PyMySQL 依赖,满足 Ansible 的 mysql_* 模块调用要求
设置 root 密码分两步:首先通过 mysqladmin 覆盖默认空密码,再逐个主机项确保远程和本地 root 登录均受控
清理匿名账户与测试数据库,防止未授权访问与潜在数据泄露
初始化应用数据库与用户
独立 Play 负责为 WordPress 创建专用数据库和访问账户,授权范围可按需细化
- name: prepare db for webapphosts: controllertasks:- name: create user {{ app_user }}mysql_user:name : "{{ app_user }}"password : "{{ app_password }}"host : "1.1.1.1" # 限定访问来源 IPpriv : "{{ app_priv }}"state : presentlogin_user : rootlogin_password: "{{ mysql_root_password }}"- name: create database db_namemysql_db:name : "{{ db_name }}"state : presentlogin_user : rootlogin_password: "{{ mysql_root_password }}"
将应用用户限制为特定 IP,可根据实际部署情景改为 % 或主机名
数据库创建后即可供后续 WordPress 安装脚本使用
部署 Nginx Web 服务器
在生产环境中常用 Nginx 提供高并发静态分发和反向代理能力,此 Play 负责安装并开机自启
- name: deploy webhosts: controllertasks:- name: install nginxyum:name : nginxstate: present- name: satrtservice:name : nginxenabled: yes
安装后建议检查 /etc/nginx/nginx.conf 默认配置,并根据安全规范隐藏版本信息、禁用不必要模块
安装与配置 PHP 环境
使用 PHP-FPM 结合 Nginx 处理动态请求,Play 中安装必要组件并将其用户组切换为 nginx
- name: deploy phphosts: controllertasks:- name: installyum:name : php,php-fpm,php-mysqlndstate: present- name: modifylineinfile:path : /etc/php-fpm.d/www.confregexp: "{{ item }} = "line : "{{ item }} = nginx"loop:- user- group- name: startservice:name : php-fpmstate : startedenabled: yes- name: config php for ngincopy:src : php.confdest: /etc/nginx/default.d/php.conf- name: restartservice:name : nginxstate: restarted
将 PHP-FPM 的进程用户和组都设置为 nginx,可以简化文件与目录权限管理
php.conf 内容示例
location ~ \.php$ {try_files $uri =404fastcgi_pass 127.0.0.1:9000fastcgi_index index.phpfastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_nameinclude fastcgi_params
}
此片段挂载到 Nginx 默认站点配置中,实现对 PHP 请求的转发
部署 WordPress 应用
通过 Jinja2 模板生成 Nginx虚拟主机配置,创建目录并将压缩包解压到指定位置
- name: deploy apphosts: controllervars:blog_vhost: blog.zhuxiaodics6.cloudtasks:- name: prepare vhosttemplate:src : wordpress.conf.j2dest: /etc/nginx/conf.d/wordpress.conf- name: creat dirfile:path : /usr/share/nginx/html/{{ blog_vhost }}state: directory- name: unarchiveunarchive:src : wordpress-4.9.4-zh_CN.zipdest : /usr/share/nginx/html/{{ blog_vhost }}/owner : nginxgroup : nginx- name: restart nginxservice:name : nginxstate: restarted
模板示例 wordpress.conf.j2
server {listen 80server_name {{ blog_vhost }}root /usr/share/nginx/html/{{ blog_vhost }}index index.php index.htmlinclude /etc/nginx/default.d/*.confaccess_log /var/log/nginx/access-{{ blog_vhost }}.logerror_log /var/log/nginx/error-{{ blog_vhost }}.log
}
解压后即完成静态文件部署,下一步可通过浏览器访问域名,进入 WordPress 安装流程
后续验证与扩展
- 使用
systemctl status检查 nginx、php-fpm、mariadb 服务状态 - 访问
http://blog.example.com完成 WordPress 安装向导 - 若需开启 SSL,可在 vhost 模板中新增证书配置并重载服务
- 安全加固可添加防火墙规则、禁用 PHP 危险函数、开启 SELinux 并调整上下文
通过该 Playbook 模块化拆分与变量化管理,运维团队能够快速部署、调试和扩展企业级博客平台
常见错误与排查
以下汇总部署过程中容易遇到的几类常见错误及解决思路,帮助快速定位并修复问题
拼写错误
- Playbook 中任务名或变量名拼写不一致容易导致任务未执行或引用失败
- 检查 YAML 文件中的键值对名称是否与 inventory、vars、模板中保持一致
- 使用
ansible-playbook --syntax-check快速校验语法与拼写错误
格式错误
- YAML 对缩进敏感,建议统一使用两个空格作为缩进
- 错误缩进会导致 Playbook 解析失败或意外将多行内容合并为同一行
- 使用 IDE 或编辑器插件(如 VSCode YAML 支持)实时提示格式问题
MySQL host 问题
mysql_user模块中的 host 字段必须与服务器实际主机名或 IP 匹配,否则无法授权或登录- 若使用
%通配,应确保权限范围正确并重载权限表 - 可通过
mysql -uroot -p -h127.0.0.1与-hlocalhost分别测试 TCP 与 socket 连接方式
模块依赖缺失
- 若报
No module named MySQLdb或pymysql,需在被管控节点安装 python2-PyMySQL 或 python3-PyMySQL - 确保 Ansible 控制机与受控端的 Python 版本和依赖保持一致
权限与 SELinux 问题
- 网站目录权限不当会导致 Nginx 或 PHP-FPM 无法读取文件,检查文件属主与属组是否为 nginx
- SELinux 开启时需通过
semanage fcontext和restorecon配置正确上下文,否则会见到 permission denied 日志
防火墙与端口访问
- 防火墙未开放 HTTP/HTTPS 端口会导致外部无法访问,使用
firewall-cmd --list-all验证当前规则 - 确保部署脚本中的
firewalld模块设置生效,并在必要时重载防火墙配置
日志排查
- Nginx 错误日志:
tail -f /var/log/nginx/error.log - PHP-FPM 日志:
tail -f /var/log/php-fpm/www-error.log - MariaDB 日志:
tail -f /var/log/mariadb/mariadb.log
日志
防火墙与端口访问
- 防火墙未开放 HTTP/HTTPS 端口会导致外部无法访问,使用
firewall-cmd --list-all验证当前规则 - 确保部署脚本中的
firewalld模块设置生效,并在必要时重载防火墙配置
日志排查
- Nginx 错误日志:
tail -f /var/log/nginx/error.log - PHP-FPM 日志:
tail -f /var/log/php-fpm/www-error.log - MariaDB 日志:
tail -f /var/log/mariadb/mariadb.log
通过以上分类定位常见错误,并结合日志信息和语法校验工具,可大幅提升故障排查效率
