00-总览README
Docker容器化部署方案 - 3节点高可用集群
项目概述
本项目部署一套基于Docker容器化的高可用Web服务集群,包含3个节点,共运行21个容器,涵盖负载均衡、PHP服务、Redis缓存集群、Redis Sentinel哨兵和MySQL MGR数据库集群。
架构特点
-
3节点部署:Node1(Node1)、Node2(Node2)、Node3(Node3)
-
VIP高可用:通过Keepalived实现虚拟IP(172.20.1.100)漂移
-
7服务冗余:每台主机都运行nginx-lb、keepalived、php、php-fpm、redis、sentinel、mysql
-
5网络隔离:frontend-net、backend-net、cache-net、database-net、manage-net
-
容器总数:21个(每节点7个)
三台VM信息
| 主机名 | IP地址 | 角色 | 容器数量 |
|---|---|---|---|
| Node1 | 192.168.64.128 | Master | 7 |
| Node2 | 192.168.64.129 | Backup1 | 7 |
| Node3 | 192.168.64.130 | Backup2 | 7(含backup-server) |
整体拓扑图
┌─────────────────────────────────────────────────────────────────────────────┐
│ 客户端访问 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ VIP: 172.20.1.100 │ ← Keepalived浮动IP │
│ └────────┬────────┘ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │Nginx-LB │ │Nginx-LB │ │Nginx-LB │ │
│ │172.20.1.11│ │172.20.1.12│ │172.20.1.13│ │
│ │ Master │ │ Backup │ │ Backup │ │
│ └────┬──────┘ └─────┬─────┘ └─────┬─────┘ │
└──────────────────│───────────────│──────────────│───────────────────────────┘
│ │ │
▼ ▼ ▼
┌────────────────────────────────────────────────┐
│ backend-net (172.20.2.0/24) │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ PHP(nginx)│ │ PHP(nginx)│ │ PHP(nginx)│ │
│ │172.20.2.11│ │172.20.2.12│ │172.20.2.13│ │
│ └────┬──────┘ └─────┬─────┘ └─────┬─────┘ │
│ ┌─────┴─────┐ ┌──────┴────┐ ┌──────┴────┐ │
│ │PHP-FPM │ │PHP-FPM │ │PHP-FPM │ │
│ │172.20.2.21│ │172.20.2.22│ │172.20.2.23│ │
│ └───────────┘ └───────────┘ └───────────┘ │
└────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ cache-net (172.20.3.0/24) │ database-net (172.20.4.0/24) │
│ │ │
│ ┌─── Redis集群 ───┐ ┌─ Sentinel集群 ───┐ │ ┌─────────────────┐ │
│ │ Redis Master │ │ Sentinel-01 │ │ │ MySQL Node1 │ │
│ │ 172.20.3.11(M) │ │ 172.20.3.31 │ │ │ 172.20.4.11(P) │ │
│ └────────┬────────┘ └───────┬────────┘ │ └────────┬────────┘ │
│ │ ←主从复制→ │ ↑监控 │ │ ←集群复制→ │
│ ┌────────┴────────┐ ┌───────┴───────┐ │ ┌────────┴────────┐ │
│ │ Redis Slave │ │ Sentinel-02 │ │ │ MySQL Node2 │ │
│ │ 172.20.3.12(S) │ │ 172.20.3.32 │ │ │ 172.20.4.12(S) │ │
│ └────────┬────────┘ └──────┬────────┘ │ └────────┬────────┘ │
│ │ │ │ │ │
│ ┌────────┴────────┐ ┌──────┴────────┐ │ ┌────────┴────────┐ │
│ │ Redis Slave │ │ Sentinel-03 │ │ │ MySQL Node3 │ │
│ │ 172.20.3.13(S) │ │ 172.20.3.33 │ │ │ 172.20.4.13(S) │ │
│ └─────────────────┘ └───────────────┘ │ └─────────────────┘ │
│ │ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ manage-net (172.20.5.0/24) │
│ ┌─────────────────────────────────────┐ │
│ │ Backup Server (Node3上) │ │
│ │ 172.20.5.13 │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
IP规划表
服务IP分配
| 节点 | nginx-lb | keepalived | php | php-fpm | redis | sentinel | mysql |
|---|---|---|---|---|---|---|---|
| Node1 | 172.20.1.11 | Master(p100) | 172.20.2.11 | 172.20.2.21 | 172.20.3.11(M) | 172.20.3.31 | 172.20.4.11 |
| Node2 | 172.20.1.12 | Backup(p90) | 172.20.2.12 | 172.20.2.22 | 172.20.3.12(S) | 172.20.3.32 | 172.20.4.12 |
| Node3 | 172.20.1.13 | Backup(p80) | 172.20.2.13 | 172.20.2.23 | 172.20.3.13(S) | 172.20.3.33 | 172.20.4.13 |
网络规划
| 网络名称 | 子网 | 网关 | 用途 |
|---|---|---|---|
| frontend-net | 172.20.1.0/24 | 172.20.1.1 | Nginx-LB、Keepalived VIP |
| backend-net | 172.20.2.0/24 | 172.20.2.1 | PHP服务、PHP-FPM |
| cache-net | 172.20.3.0/24 | 172.20.3.1 | Redis、Sentinel |
| database-net | 172.20.4.0/24 | 172.20.4.1 | MySQL MGR |
| manage-net | 172.20.5.0/24 | 172.20.5.1 | 备份服务(仅Node3) |
技术组件说明
Nginx-LB (负载均衡器)
-
镜像:
nginx:alpine -
作用:接收客户端请求,负载分发到后端PHP服务
-
配置:upstream指向3个PHP服务的IP
Keepalived (高可用)
-
镜像:
ednxzu/keepalived:2.3.4 -
作用:实现VIP漂移,保证服务高可用
-
VRRP协议,3节点各有不同优先级
PHP服务 (双容器架构)
-
PHP容器:
nginx:alpine(静态文件服务) -
PHP-FPM容器:
php:8.2-fpm-alpine(动态PHP处理) -
通信:fastcgi_pass通过外部IP转发
Redis集群
-
主节点:172.20.3.11 (Master)
-
从节点:172.20.3.12、172.20.3.13 (Slave)
-
哨兵:3个Sentinel监控主节点状态
Sentinel (哨兵)
-
镜像:
redis:7-alpine -
作用:Redis自动故障转移
-
监控mymaster主节点,2票生效
MySQL MGR (组复制集群)
-
单主模式,Node1为Primary
-
3节点通过33061端口通信
-
GTID事务复制
文件清单
Docker容器化部署方案/
├── docker-compose-node1.yml # Node1服务编排
├── docker-compose-node2.yml # Node2服务编排
├── docker-compose-node3.yml # Node3服务编排
├── config/
│ ├── nginx-lb/
│ │ ├── nginx.conf # Nginx主配置
│ │ ├── conf.d/upstream.conf # upstream配置
│ │ └── ssl.conf # SSL配置
│ ├── keepalived/
│ │ ├── keepalived_master.conf # Master配置
│ │ ├── keepalived_backup.conf # Backup1配置
│ │ ├── keepalived_backup2.conf # Backup2配置
│ │ ├── check_nginx.sh # Nginx检查脚本
│ │ └── notify.sh # 状态通知脚本
│ ├── php/
│ │ ├── php-node1.conf # Node1 PHP配置
│ │ ├── php-node2.conf # Node2 PHP配置
│ │ ├── php-node3.conf # Node3 PHP配置
│ │ └── php.ini # PHP运行时配置
│ ├── redis/
│ │ ├── redis-master.conf # Redis主配置
│ │ ├── redis-slave.conf # Redis从配置
│ │ └── sentinel.conf # 哨兵配置
│ └── mysql/
│ ├── my-node1.cnf # Node1 MySQL配置
│ ├── my-node2.cnf # Node2 MySQL配置
│ ├── my-node3.cnf # Node3 MySQL配置
│ └── init.sql # 初始化SQL
├── scripts/
│ └── backup.sh # 备份脚本
├── 00-总览README.md
├── 01-环境准备.md
├── 02-网络创建.md
├── 03-目录创建.md
├── 04-创建配置文件.md
├── 05-Nginx-LB配置详解.md
├── 06-Keepalived配置详解.md
├── 07-PHP服务配置详解.md
├── 08-Redis配置详解.md
├── 09-Sentinel配置详解.md
├── 10-MySQL配置详解.md
├── 11-MySQL-MGR初始化.md
├── 12-验证测试.md
├── 13-快速部署.md
├── 14-运维手册.md
└── 答辩演讲稿.md
快速开始步骤
1. 环境准备
# 在所有节点执行
curl -fsSL https://get.docker.com | bash
systemctl enable docker
systemctl start docker
docker compose version
2. 创建网络
# 在所有节点执行
docker network create -d macvlan --subnet=172.20.1.0/24 --gateway=172.20.1.1 -o parent=ens33 frontend-net
docker network create -d macvlan --subnet=172.20.2.0/24 --gateway=172.20.2.1 -o parent=ens33 backend-net
docker network create -d macvlan --subnet=172.20.3.0/24 --gateway=172.20.3.1 -o parent=ens33 cache-net
docker network create -d macvlan --subnet=172.20.4.0/24 --gateway=172.20.4.1 -o parent=ens33 database-net
docker network create -d macvlan --subnet=172.20.5.0/24 --gateway=172.20.5.1 -o parent=ens33 manage-net
3. 创建目录
mkdir -p /opt/cluster-deploy/{config/{nginx-lb/{conf.d},keepalived,php,redis,mysql},scripts}
4. 部署服务
# Node1
docker compose -f docker-compose-node1.yml up -d
# Node2
docker compose -f docker-compose-node2.yml up -d
# Node3
docker compose -f docker-compose-node3.yml up -d
5. 初始化MySQL MGR
# 在Node1 MySQL中执行
docker exec -it mysql-01 mysql -uroot -p'YourStr0ng!Pass' -h127.0.0.1
详见 13-快速部署.md
关键修复记录(13个排错经验)
1. Docker Compose V5兼容
-
问题:旧版本语法不兼容
-
修复 :删除
version行,使用docker compose(空格)而非docker-compose(连字符)
2. Keepalived hostname冲突
-
问题 :
network_mode: service:xxx时不能设置hostname -
修复:删除hostname配置或使用network_mode: host
3. 配置文件挂载变目录
-
问题:挂载的配置文件不存在时,Docker会创建目录导致启动失败
-
修复 :必须先创建所有配置文件,再执行
docker compose up
4. MySQL socket路径
-
问题:容器内socket连接可能失败
-
修复 :使用
-h 127.0.0.1强制TCP连接
5. MySQL GTID未开启
-
问题:MGR要求GTID模式
-
修复 :
gtid_mode=ON和enforce_gtid_consistency=ON
6. 配置写入错误段
-
问题:配置写入错误的段导致不生效
-
修复 :MGR参数必须写在
[mysqld]段,不是[mysql]段;使用cat >覆盖写法
7. MGR恢复通道DNS
-
问题:Macvlan网络无DNS解析
-
修复 :
report_host=IP使用IP地址
8. caching_sha2_password兼容
-
问题:MGR复制用户不支持新认证插件
-
修复 :创建复制用户时使用
mysql_native_password
9. osixia/keepalived模板覆盖
-
问题:镜像环境变量会覆盖自定义配置
-
修复:自定义entrypoint绕过模板系统
10. Redis 7.x兼容
-
问题:旧配置项在新版本中已废弃
-
修复 :删除
active-rehashing配置
11. Redis日志权限
-
问题:非root用户无法写日志文件
-
修复 :
logfile ""输出到stdout
12. Sentinel配置只读
-
问题:Sentinel需要写入状态
-
修复 :不能挂载为
:ro
13. MySQL healthcheck
-
问题 :mysqladmin不支持
--no-auth-warning参数 -
修复:从healthcheck命令中删除该参数