ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MySQL+NFS+Zabbix:企业级服务部署与监控环境搭建全流程

MySQL+NFS+Zabbix:企业级服务部署与监控环境搭建全流程 2. 架构规划与方案选型2.1 拓扑设计与服务角色划分先把整体拓扑理清楚。这套环境包含五类核心服务节点每一类承担不同的职责服务角色核心功能关键端口对外依赖数据库服务存储业务数据、账号信息、监控指标3306依赖存储卷共享存储服务为 Web 节点提供统一文件存储2049依赖网络与权限配置Web 服务对外提供业务页面与应用接口80/443依赖数据库与共享存储监控服务采集各节点指标、触发告警10051/10050依赖数据库存储监控数据客户端节点被监控对象上报运行状态10050依赖网络连通性其中数据库服务和监控服务是整套环境的数据中枢Web 服务和共享存储服务则承担业务入口与文件分发职责。我建议的画法是先画三个独立区域——存储区、业务区、监控区再用箭头把数据流向标注清楚这样后续排查问题时能一眼定位瓶颈。2.2 服务生命周期规划用一张表格记录每个服务的部署顺序、依赖关系和预估耗时能明显降低部署时的混乱度:序号服务名称依赖项预估耗时说明1MySQL无15分钟初始化 root 密码创建业务库2NFS网络互通10分钟配置导出目录与客户端白名单3WebMySQL、NFS20分钟安装服务挂载存储连接数据库4Zabbix ServerMySQL25分钟导入表结构配置前端与告警5Zabbix Agent网络互通10分钟在被监控节点安装并配置提示监控服务必须在数据库服务稳定运行后再部署否则初始化阶段会因为无法连接数据库而反复报错。3. 部署数据库服务 MySQL3.1 安装与基础初始化我选用通用的二进制包或系统软件源安装方式。以系统软件源为例先更新索引再安装 MySQL 服务端和客户端apt update apt install -y mysql-server mysql-client systemctl enable --now mysql安装完成后MySQL 默认监听在本机 3306 端口需要手动确认状态ss -lntp | grep 3306接着执行安全性初始化脚本mysql_secure_installation这个过程会引导你设置 root 密码、删除匿名用户、禁止 root 远程登录视需求而定以及清理测试库。生产环境建议全部选 yes测试环境可保留 root 本机登录。3.2 创建业务数据库与专用账号Web 应用和 Zabbix 都不能直接用 root 连数据库这是基本素养。我们为每个业务创建独立账号和库CREATE DATABASE IF NOT EXISTS webapp DEFAULT CHARSET utf8mb4; CREATE USER webuser% IDENTIFIED BY StrongPass_2024; GRANT ALL PRIVILEGES ON webapp.* TO webuser%; CREATE DATABASE IF NOT EXISTS zabbix DEFAULT CHARSET utf8mb4; CREATE USER zabbix% IDENTIFIED BY ZabbixPass_2024; GRANT ALL PRIVILEGES ON zabbix.* TO zabbix%; FLUSH PRIVILEGES;注意虽然示例中授权给%但在安全要求高的环境里建议限定为应用服务器的实际 IP比如webuser192.168.10.0/255.255.255.0。MySQL 的账号权限控制是基于“用户 来源主机”的组合配错来源会直接导致应用连接失败。3.3 调优关键参数默认配置面向通用场景但作为监控后端和业务后端需要针对性调整[mysqld] character-set-server utf8mb4 collation-server utf8mb4_general_ci max_connections 500 innodb_buffer_pool_size 2G innodb_flush_log_at_trx_commit 2 slow_query_log 1 slow_query_log_file /var/log/mysql/slow.log long_query_time 2utf8mb4是必须的否则中文和 emoji 字符会出现乱码。innodb_buffer_pool_size建议设置为物理内存的 50% 到 70%比如 4G 内存的机器就设 2G 左右。innodb_flush_log_at_trx_commit设为 2 可以在性能和数据安全之间取得平衡对监控类高频小写入尤其友好。修改后重启服务systemctl restart mysql4. 部署共享存储服务 NFS4.1 安装与目录规划NFS 的价值在于让多个 Web 节点共享同一份文件数据这样用户上传的图片、附件不会因为请求落在不同节点上而出现不一致。我们在一台独立存储服务器上操作apt install -y nfs-kernel-server mkdir -p /data/www chown -R nobody:nogroup /data/www我习惯把导出目录放在独立挂载点/data下不要把根分区直接共享出去方便做容量配额和快照备份。权限方面NFS 默认会做 squash 映射将客户端 root 映射为 nobody可以降低越权风险。4.2 导出目录配置编辑/etc/exports/data/www 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)这里几个参数逐个说明rw允许读写sync写入时同步落盘防止断电丢数据no_subtree_check减少目录权限检查开销适合高频访问场景no_root_squash允许客户端 root 保留权限。在生产环境中我通常不加这个参数而是让客户端用普通用户写入再通过属主和权限位控制访问导出配置生效exportfs -rav systemctl enable --now nfs-server showmount -e localhostshowmount能看到当前导出的目录是最快的自检方式。如果输出为空或报错优先排查 exports 文件格式和 NFS 服务状态。4.3 客户端挂载与自动挂载配置Web 节点上的挂载操作apt install -y nfs-common mkdir -p /var/www/html mount -t nfs 192.168.10.20:/data/www /var/www/html df -h | grep nfs重启后要自动挂载需要写入/etc/fstab192.168.10.20:/data/www /var/www/html nfs defaults,_netdev,noatime 0 0_netdev是关键参数它告诉系统在网络就绪后再挂载 NFS否则开机时网络未启动会导致挂载失败。noatime能减少访问时间戳的写入次数对文件密集访问场景有明显性能提升。注意NFS 挂载后在客户端上用df -h看到的容量是存储服务器的容量而不是本机磁盘容量。之前有同学误以为挂载失败其实只是被这个表象误导了。5. 配置网站服务5.1 安装与虚拟主机配置Web 服务选择最常见的组合安装 Nginx 和 PHP 相关组件apt install -y nginx php-fpm php-mysql systemctl enable --now nginx php-fpm在/etc/nginx/sites-available/下新增加站点配置server { listen 80; server_name web.internal.local; root /var/www/html; index index.php index.html; location / { try_files $uri $uri/ 404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php-fpm.sock; } }启用配置并测试ln -s /etc/nginx/sites-available/webapp /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx一个常被忽略的点是 PHP 与 Nginx 的通信方式。上面用的是 Unix Socket性能比 TCP 回环更好但 socket 文件的权限和路径必须和 PHP-FPM 池配置一致。如果 Nginx 报connect() to unix:/run/php/php-fpm.sock failed多半是 socket 路径不匹配或 PHP-FPM 没起来。5.2 测试页面与数据库连通性验证在 Web 根目录下创建测试文件?php $conn new mysqli(192.168.10.10, webuser, StrongPass_2024, webapp); if ($conn-connect_error) { die(数据库连接失败: . $conn-connect_error); } echo 数据库连接成功; ?用浏览器或 curl 验证curl -I http://192.168.10.30如果看到 HTTP/1.1 200 OK说明 Web 服务本身正常。再访问测试 PHP 页面确认数据库连通性。这一步是整个环境的一个关键联调点——前面所有服务最终都要通过这个页面体现价值。5.3 NFS 与 Web 的协同Web 根目录已经通过 NFS 挂载了存储服务器的目录。测试上传文件时文件会实际写入存储服务器。Web 节点本身只跑应用所有静态资源和上传文件都落在 NFS 上。这样做的直接收益是多台 Web 节点看到的文件内容完全一致扩容 Web 节点时无需同步文件备份只需针对存储服务器执行提示务必验证 NFS 的读写权限。Web 进程通常是www-data需要对挂载目录有写权限否则上传功能会报权限错误。最简单的方法是sudo -u www-data touch /var/www/html/test.txt能创建文件就说明权限没问题。6. 部署监控服务 Zabbix6.1 安装 Zabbix Server 与前端Zabbix 是整套环境中的监控中枢。安装过程分三部分服务端、前端、Agent。先安装服务端和前端wget https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_6.0ubuntu22.04_all.deb dpkg -i zabbix-release_latest_6.0ubuntu22.04_all.deb apt update apt install -y zabbix-server-mysql zabbix-frontend-php zabbix-nginx-conf zabbix-sql-scripts6.2 初始化数据库与导入表结构Zabbix 的数据表结构由官方 SQL 脚本直接导入。这一步比较耗时因为表数量和索引都很多zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-setutf8mb4 -uzabbix -pZabbixPass_2024 zabbix导入完成后配置服务端连接数据库编辑/etc/zabbix/zabbix_server.confDBHost192.168.10.10 DBNamezabbix DBUserzabbix DBPasswordZabbixPass_2024 DBPort3306启动服务端systemctl enable --now zabbix-server tail -f /var/log/zabbix/zabbix_server.log日志里看到Zabbix Server started就说明启动成功。如果卡在cannot start alert manager service之类的问题大概率是数据库配置不对或表结构没导入完整。6.3 前端配置与 Nginx 集成Zabbix 前端依赖 Nginx 提供访问入口。修改/etc/zabbix/nginx.conf中的监听端口避免与已有 Web 站点冲突listen 8080; server_name zabbix.internal.local;然后启用 PHP-FPM 配置并重启相关服务ln -s /etc/zabbix/nginx.conf /etc/nginx/sites-enabled/ systemctl restart zabbix-server zabbix-agent nginx php-fpm浏览器访问http://192.168.10.40:8080进入安装向导按提示填入数据库连接信息和 Zabbix Server 地址。安装完成后用默认账号Admin/zabbix登录登录后第一时间修改默认密码这是安全基线要求。6.4 Agent 安装与主机监控接入被监控节点上安装 Agentapt install -y zabbix-agent修改/etc/zabbix/zabbix_agentd.confServer192.168.10.40 ServerActive192.168.10.40 Hostnameweb1注意Server和ServerActive都要指向 Zabbix Server 的 IP。这两个参数作用不同——前者用于被动模式Server 拉取数据后者用于主动模式Agent 上报数据。只配一个的话对应模式的监控项将无法获取数据。启动并验证systemctl enable --now zabbix-agent ss -lntp | grep 10050然后在 Zabbix 前端界面选择“主机” → “创建主机”填入主机名、可见名称和 Agent 接口 IP。添加模板时建议选择Linux by Zabbix agent内置了 CPU、内存、磁盘、网络等常用监控项和触发器。添加后等待几分钟如果最新数据页面有值出现说明监控链路已打通。7. 测试配置与联调验证7.1 分层验证策略我把整个联调过程拆成四层逐层向上哪一层失败就只排查哪一层效率最高层级验证内容工具/方式网络层各节点间连通性ping、telnet服务层各服务独立运行状态systemctl status、ss数据层数据库读写、共享存储读写mysql 查询、文件创建业务层页面访问、监控数据采集curl、浏览器、Zabbix 最新数据网络层可以用ping验证 ICMP 连通性用telnet IP 端口验证端口可达性。服务层用systemctl status检查各服务运行状态。数据层已经在前面的小节中穿插验证过了。业务层是最终验收标准。7.2 端口连通性速查各服务的关键端口如下服务端口验证方式MySQL3306telnet 192.168.10.10 3306NFS2049showmount -e 192.168.10.20Web80curl -I http://192.168.10.30Zabbix Server10051telnet 192.168.10.40 10051Zabbix Agent10050telnet 192.168.10.40 10050凡是端口不通的情况先确认服务本身状态再检查防火墙规则。Ubuntu 环境常见的是ufw未放行对应端口ufw allow 3306/tcp ufw allow 2049/tcp ufw allow 80/tcp ufw allow 10050/tcp ufw allow 10051/tcp7.3 全链路业务验证最终验证脚本可以这样写一次性检查所有关键节点echo 数据库服务 systemctl is-active mysql echo NFS 服务 showmount -e 192.168.10.20 echo Web 服务 curl -s -o /dev/null -w %{http_code} http://192.168.10.30 echo Zabbix Server systemctl is-active zabbix-server echo Zabbix Agent systemctl is-active zabbix-agent echo MySQL 业务表 mysql -h192.168.10.10 -uwebuser -pStrongPass_2024 -e SHOW DATABASES; webapp如果全部返回预期值说明整套环境已经跑通。如果任何一步失败就按前面表格中的层次定位问题不要跳过跨层排查。8. 常见问题与排查技巧实录8.1 数据库服务常见问题问题现象应用报错Access denied for user webuser...这个报错 80% 是账号授权来源主机与实际连接来源不匹配。MySQL 在匹配账号时会同时校验用户名和来源 IP即使密码正确只要来源不在授权范围内就会拒绝。排查方法SELECT user, host FROM mysql.user WHERE user webuser;如果 host 是localhost而应用从远程连接就必然失败。重新授权并刷新即可。问题现象数据库连接超时优先检查端口监听ss -lntp | grep 3306输出为空说明 MySQL 没监听或只监听了回环地址。查看/etc/mysql/mysql.conf.d/mysqld.cnf中的bind-address配置如果值是127.0.0.1改为0.0.0.0或指定网卡 IP 后重启。8.2 NFS 共享存储常见问题问题现象客户端挂载时报mount.nfs: access denied直接查看存储服务器的导出列表和日志showmount -e 192.168.10.20 tail -f /var/log/syslog | grep -i nfs日志中通常能看到refused mount request from IP for /data/www这说明 exports 中的网段白名单没有包含客户端来源。修改/etc/exports后执行exportfs -rav即可。问题现象文件权限错乱或无法写入先确认挂载参数mount | grep nfs如果显示rw但依然无法写入看 Web 进程身份是否对目录有权限。最直接的验证方式sudo -u www-data touch /var/www/html/test-write.txt失败则调整目录属主或权限chown -R www-data:www-data /data/www8.3 Zabbix 监控链路常见问题问题现象主机被标记为不可达但 Agent 明明在运行这种情况最常见的原因是 Agent 的Server配置里没有包含 Zabbix Server 的 IP。Agent 默认只信任配置文件中Server参数指定的来源。修改后重启 Agentsystemctl restart zabbix-agent然后检查 Agent 日志tail -f /var/log/zabbix/zabbix_agentd.log问题现象监控项一直无数据先确认端口ss -lntp | grep 10050 ss -lntp | grep 10051再确认 Zabbix Server 日志中是否出现 Agent 连接记录。还可以在 Server 上手动执行一次监控项对应的命令比如zabbix_get -s 192.168.10.30 -k system.cpu.load[all,avg1]如果zabbix_get返回空或超时问题多半在 Agent 参数或防火墙如果返回了值但前端无数据问题多半在模板或主机配置。8.4 防火墙与网络基线防火墙是我见过最隐蔽的坑。很多服务在服务器本地用ss查看是正常的但跨节点访问就失败基本都被防火墙拦截。在部署之前最好先建立网络基线# 在控制节点上统一探测 for port in 3306 2049 80 10050 10051; do timeout 3 bash -c echo /dev/tcp/192.168.10.10/$port 2/dev/null echo $port open || echo $port closed done提示放行规则遵循最小化原则。数据库端口只给应用网段访问Web 和 Zabbix 端口按实际访问方放行不要图省事直接ufw allow all。我见过不少环境因为防火墙规则过宽被扫描工具通过各种端口打进来而监控系统对这种低频扫描往往没有及时告警。9. 部署顺序复盘与调优建议9.1 为什么必须按“数据库→存储→Web→监控”的顺序整个部署顺序不是随手排的而是由依赖关系决定的。数据库先就绪后续 Web 服务和 Zabbix 才能初始化各自的数据结构。NFS 先就绪Web 节点才能把站点目录完整挂载起来。而监控服务放在最后是因为它的核心价值在于“监控已有服务”——如果服务本身还没部署完监控链路再通也没有意义。反过来如果把 Zabbix 放到最前面部署Agent 确实可以提前装好但被监控项大部分是空的前端界面会自动生成一堆“不支持”状态的监控项反而干扰排查并增加学习成本。按依赖顺序推进每一步的验证结果都能成为下一步的输入联调成本最低。9.2 针对当前环境的优化方向确认整套环境稳定运行之后有几个方向值得继续投入数据库备份策略用mysqldump做逻辑备份结合定时任务写全量备份脚本数据量变大后改用XtraBackup做物理备份恢复速度更快。NFS 高可用单点 NFS 是整套环境里的风险集中点。可以用主备模式加rsync同步或者直接引入分布式文件系统把存储层的高可用做起来。Web 节点会话共享多台 Web 节点接入负载均衡后PHP 默认的本地会话会互相冲突。需要把会话存储迁移到 Redis 或数据库层保证用户登录状态不丢失。Zabbix 告警接入配置邮件或企业微信等媒介作为告警通道把监控数据变成有效告警。没有告警触发的监控系统只能算图表工具。9.3 安全基线补充安全方面注意几件小事所有默认密码登录后立即修改包括 MySQL root、Zabbix Admin数据库和 Zabbix 前端的管理面不要暴露在业务网段之外能不加公网 IP 就不加Agent 和 Server 之间用固定来源 IP 白名单的方式控制连接定期检查/var/log/mysql/slow.log和 Zabbix 的审计日志留意异常查询和登录尝试10. 总结整套环境的部署核心在于理清服务间的依赖关系和数据流向。数据库为业务和监控提供数据底座NFS 解决 Web 节点的文件一致性问题Zabbix 把前面所有服务的运行状态汇集到统一的监控视图。按“先底座、再存储、后业务、终监控”的顺序推进每完成一个环节就当场验证能够把最常见的联调问题消灭在早期。我在实际操作中的体会是最容易出问题的其实不是安装命令本身而是配置细节账号授权来源、NFS 导出网段、Agent 的 Server 参数、防火墙放行规则。这些配置错任何一个表面现象都是“连不上”或“没数据”但根因各不相同。建议把每一类配置项都记录到自己的部署笔记中形成一套可复用的检查清单下次重复部署时能省下大量排查时间。最后再分享一个小技巧在所有服务部署完成之后先把 Zabbix 的告警规则设起来再人为触发一次故障比如停掉 Web 服务确认告警能正常收到。这个动作花不了十分钟却能让整个监控体系真正可信。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进