第 4/15 天 · Ceph+K8s 中间件实战系列
在 Day 2 和 Day 3 中,我们分别完成了 Ceph RBD 块存储和 CephFS 共享文件存储接入 K8s 的全部配置。从本篇开始,系列正式进入中间件部署阶段——我们将逐一在 K8s 上部署各类核心中间件,所有持久化存储统一对接 Ceph 后端。MySQL 作为最经典的关系型数据库,是绝大多数业务系统的数据底座。本篇将讲解如何在 K8s 上通过 Bitnami Helm Chart 部署 MySQL 高可用集群,使用 Ceph RBD StorageClass 提供持久化存储,并给出架构设计、部署实战、登录验证与日常巡检的完整流程。

一、设计架构:MySQL on K8s 高可用体系
1.1 组件拓扑
在 K8s 上部署 MySQL 高可用集群,核心目标是实现数据持久化、读写分离与故障自动恢复。Bitnami MySQL Helm Chart 提供了 Primary + Secondary 的主从架构模式,结合 K8s 的 StatefulSet 与 Headless Service 实现稳定网络标识。整体组件拓扑如下:
| 组件 | 角色说明 | 数量/规格 |
|---|---|---|
| MySQL Primary | 主节点,负责读写操作,Binlog 同步到从节点 | 1 个 |
| MySQL Secondary | 从节点,负责只读负载,实时复制主节点数据 | 1-2 个 |
| Headless Service | 为 StatefulSet 提供稳定 DNS 名称(pod-0.mysql-headless) | 1 个 |
| ClusterIP Service | 对外暴露统一访问入口,读写分离路由 | 1 个 |
| PVC(Ceph RBD) | 每个 Pod 独占一块 RBD Image,ReadWriteOnce 模式 | 每节点 1 个 |
| ConfigMap | 存放 MySQL 配置文件(my.cnf 自定义参数) | 1 个 |
| Secret | 存储 root 密码、复制账户密码等敏感信息 | 1 个 |
1.2 数据流向
应用 Pod → ClusterIP Service → MySQL Primary(写)
↓ Binlog Replication
MySQL Secondary-0(读)
MySQL Secondary-1(读)
Primary PVC ←→ Ceph RBD Image ←→ Ceph OSD Pool
Secondary PVC ←→ Ceph RBD Image ←→ Ceph OSD Pool
写入请求通过 ClusterIP Service 路由到 Primary 节点,Primary 将变更写入 Binlog 后异步推送到 Secondary 节点重放。每个 MySQL Pod 通过 PVC 绑定独立的 Ceph RBD Image,RBD 的 ReadWriteOnce 模式天然保证单 Pod 独占挂载,避免多写冲突。
1.3 高可用机制
故障检测与切换:当 Primary Pod 所在节点宕机,K8s 会自动在健康节点重新拉起 StatefulSet Pod。由于数据持久化在 Ceph RBD 上,新 Pod 重新挂载同一 PVC 即可恢复数据。Primary 身份由 Chart 内置脚本检测:
- Pod
mysql-0默认为 Primary,mysql-1、mysql-2为 Secondary - 若 Primary Pod 被驱逐,StatefulSet 滚动重建保证
mysql-0优先恢复 - 从节点在 Primary 恢复后自动重新建立复制关系
数据冗余:Ceph RBD 后端默认三副本存储,即使单个 OSD 或节点故障,数据仍可从其他副本读取。MySQL 层面的主从复制提供了应用级数据冗余,Ceph 层面的多副本提供了存储级冗余,双重保障。
1.4 存储规划
| 存储层 | 类型 | 模式 | 用途 |
|---|---|---|---|
| K8s StorageClass | ceph-rbd-sc | WaitForFirstConsumer | 动态 Provisioning |
| PVC | mysql-data | ReadWriteOnce | 每 Pod 独占数据卷 |
| Ceph Pool | k8s-rbd-pool | 副本数 3 | 后端对象存储池 |
| RBD Image | mysql-data-mysql-0 | 动态创建 | 20Gi per Pod |
二、部署实战:Bitnami MySQL Helm Chart
本篇使用 Bitnami 官方维护的 bitnami/mysql Helm Chart,该 Chart 原生支持 Primary+Secondary 架构、自定义 StorageClass、资源限制与密码管理。
2.1 添加 Bitnami Helm 仓库
# 添加 Bitnami 官方 Chart 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新本地 Chart 索引
helm repo update
# 搜索 mysql chart 确认可用
helm search repo bitnami/mysql
# 查看 chart 版本信息
helm show chart bitnami/mysql
2.2 编写 values.yaml 自定义配置
# mysql-values.yaml — Ceph RBD 持久化 MySQL 集群配置
architecture: replication # 主从复制模式
primary:
persistence:
enabled: true
storageClass: "ceph-rbd-sc" # 对接 Day 2 创建的 Ceph RBD StorageClass
accessModes:
– ReadWriteOnce
size: 20Gi
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
mysqlUser: "appuser"
mysqlDatabase: "appdb"
secondary:
replicaCount: 2 # 2 个从节点
persistence:
enabled: true
storageClass: "ceph-rbd-sc"
accessModes:
– ReadWriteOnce
size: 20Gi
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
auth:
rootPassword: "Ceph@K8s#2026" # 生产环境建议使用 Secret 注入
replicationPassword: "Repl#Pass2026"
metrics:
enabled: true # 开启 Prometheus 指标暴露
serviceMonitor:
enabled: false # 如已安装 Prometheus Operator 可开启
2.3 执行 Helm 部署
# 创建独立命名空间
kubectl create namespace middleware
# 部署 MySQL 集群
helm install mysql bitnami/mysql
–namespace middleware
-f mysql-values.yaml
–version 11.x.x
# 查看 Helm Release 状态
helm list -n middleware
# 等待 Pod 就绪(通常需要 1-3 分钟)
kubectl wait –for=condition=Ready pods -n middleware -l app.kubernetes.io/instance=mysql –timeout=300s
2.4 验证 Pod / Service / PVC 状态
# 查看 Pod 运行状态,确认 primary 和 secondary 全部 Running
kubectl get pods -n middleware -l app.kubernetes.io/instance=mysql -o wide
# 查看 Service 列表
kubectl get svc -n middleware -l app.kubernetes.io/instance=mysql
# 查看 PVC 绑定情况,确认 STORAGECLASS 为 ceph-rbd-sc
kubectl get pvc -n middleware -l app.kubernetes.io/instance=mysql
预期输出示例:
NAME READY STATUS RESTARTS AGE
mysql-primary-0 1/1 Running 0 3m
mysql-secondary-0 1/1 Running 0 2m
mysql-secondary-1 1/1 Running 0 2m
NAME TYPE CLUSTER-IP PORT(S) AGE
mysql-primary ClusterIP 10.96.23.45 3306/TCP 3m
mysql-secondary ClusterIP 10.96.23.67 3306/TCP 3m
mysql-primary-hl ClusterIP None 3306/TCP 3m
mysql-secondary-hl ClusterIP None 3306/TCP 3m
NAME STATUS VOLUME CAPACITY STORAGECLASS AGE
data-mysql-primary-0 Bound pvc-xxxx 20Gi ceph-rbd-sc 3m
data-mysql-secondary-0 Bound pvc-yyyy 20Gi ceph-rbd-sc 2m
data-mysql-secondary-1 Bound pvc-zzzz 20Gi ceph-rbd-sc 2m

三、登录验证:连接 MySQL 集群
3.1 集群内部连接(Pod 内)
# 获取 root 密码
ROOT_PASSWORD=$(kubectl get secret –namespace middleware mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)
# 进入 Primary Pod 执行 MySQL 客户端
kubectl exec -it -n middleware mysql-primary-0 —
mysql -uroot -p"$ROOT_PASSWORD"
# 在 MySQL 命令行中验证主从复制状态
3.2 验证主从复制状态
— 在 Primary 节点执行,查看 Binlog 位置
SHOW MASTER STATUS;
— 查看从节点连接信息
SELECT host, user, port FROM mysql.user WHERE user='monitor' OR user='replicator';
— 在 Secondary 节点执行,查看复制状态
SHOW REPLICA STATUSG
— 关键指标确认:
— Slave_IO_Running: Yes
— Slave_SQL_Running: Yes
— Seconds_Behind_Master: 0
— 创建测试数据库验证数据同步
CREATE DATABASE IF NOT EXISTS test_ha;
USE test_ha;
CREATE TABLE t1 (id INT PRIMARY KEY, msg VARCHAR(100));
INSERT INTO t1 VALUES (1, 'Ceph RBD MySQL HA Test');
— 切换到 Secondary Pod 验证数据已同步
— kubectl exec -it -n middleware mysql-secondary-0 — mysql -uroot -p"$ROOT_PASSWORD" -e "SELECT * FROM test_ha.t1;"
3.3 集群外部连接验证
# 端口转发到本地验证(临时调试)
kubectl port-forward -n middleware svc/mysql-primary 3306:3306 &
# 使用本地 MySQL 客户端连接
mysql -h 127.0.0.1 -P 3306 -uroot -p"$ROOT_PASSWORD" -e "SELECT @@hostname, @@version;"
— 确认连接到 Primary 节点,版本号正确
四、日常巡检:MySQL 集群运维命令
4.1 健康检查
# 检查所有 Pod 状态及运行时间
kubectl get pods -n middleware -l app.kubernetes.io/instance=mysql
# 检查 Pod 详细事件(排查启动失败)
kubectl describe pod -n middleware mysql-primary-0
# 检查 PVC 绑定状态与容量
kubectl get pvc -n middleware -l app.kubernetes.io/instance=mysql
# 检查 Ceph RBD Image 是否在 Ceph 端正常创建
# 在 Ceph 容器或节点上执行
rbd ls -p k8s-rbd-pool | grep mysql
4.2 日志查看
# 查看 Primary 节点 MySQL 日志(错误日志)
kubectl logs -n middleware mysql-primary-0 –tail=100
# 查看 Secondary 节点日志
kubectl logs -n middleware mysql-secondary-0 –tail=100
# 实时跟踪日志输出
kubectl logs -n middleware mysql-primary-0 -f
# 查看 Helm Release 部署历史
helm history mysql -n middleware
4.3 性能监控
# 进入 MySQL 查看连接数与运行线程
kubectl exec -it -n middleware mysql-primary-0 —
mysql -uroot -p"$ROOT_PASSWORD" -e "
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Slow_queries';
SHOW STATUS LIKE 'Innodb_buffer_pool_wait_free';
SHOW VARIABLES LIKE 'max_connections';
"
# 查看 MySQL 复制延迟
kubectl exec -it -n middleware mysql-secondary-0 —
mysql -uroot -p"$ROOT_PASSWORD" -e "SHOW REPLICA STATUSG" |
grep -E "Seconds_Behind_Master|Slave_IO_Running|Slave_SQL_Running"
4.4 容量巡检
# 查看 PVC 实际使用量(需要 metrics-server)
kubectl get pvc -n middleware -l app.kubernetes.io/instance=mysql
-o custom-columns=NAME:.metadata.name,STATUS:.status.phase,CAPACITY:.status.capacity.storage
# 在 MySQL 内查看数据库大小
kubectl exec -it -n middleware mysql-primary-0 —
mysql -uroot -p"$ROOT_PASSWORD" -e "
SELECT table_schema AS 'Database',
ROUND(SUM(data_length+index_length)/1024/1024, 2) AS 'Size (MB)'
FROM information_schema.tables
GROUP BY table_schema;
"
# 在 Ceph 端查看 Pool 容量使用
# ceph df | grep k8s-rbd-pool
五、常见问题
Q1:PVC 一直 Pending,无法绑定 Ceph RBD?
常见原因:① Ceph RBD StorageClass 名称与 values.yaml 中的 storageClass 不一致;② CSI Driver 未正确安装或缺少 Ceph Monitor 地址;③ Ceph Pool 不存在或权限不足。排查命令:kubectl describe pvc <name> -n middleware 查看 Events 信息,确认 StorageClass 存在(kubectl get sc),以及 CSI Driver 运行正常(kubectl get pods -n ceph-csi-rbd)。
Q2:Secondary 节点复制延迟过大(Seconds_Behind_Master > 60)?
主因通常是网络带宽不足或从节点 I/O 性能瓶颈。排查步骤:① 检查从节点资源是否达到 limit 上限(kubectl top pod);② 检查 Ceph RBD IOPS 是否受限(Ceph 端 rbd perf image iotop);③ 优化 MySQL 参数如增大 innodb_buffer_pool_size、relay_log_size。在网络抖动场景可临时调大 slave_net_timeout。
Q3:Primary Pod 重建后从节点无法自动重连?
确认 Chart 版本是否支持自动复制重建。较老版本需手动执行 CHANGE REPLICATION SOURCE TO ...。建议升级到最新 bitnami/mysql Chart,新版本 Init Container 会自动检测 Primary 变更并重新建立复制关系。同时确保 Headless Service DNS 解析正常:kubectl run dns-test --rm -it --image=busybox -- nslookup mysql-primary-0.mysql-primary-hl.middleware.svc.cluster.local。
六、总结
本篇完成了 MySQL 高可用集群在 K8s 上的部署,核心要点回顾:
- 架构设计:采用 Bitnami Chart 的 Primary + Secondary 主从复制架构,每个 Pod 独占 Ceph RBD PVC,双重数据冗余保障
- 存储对接:values.yaml 中
storageClass: ceph-rbd-sc实现动态 Provisioning,无需手动预创建 RBD Image - 部署方式:全程使用 Helm Chart,一条
helm install命令完成集群部署,版本可追溯、配置可版本化管理 - 验证与巡检:通过
SHOW REPLICA STATUS确认复制链路,通过kubectl get pvc确认存储绑定,通过 Cephrbd ls确认后端 Image
Ceph RBD 的 ReadWriteOnce 特性天然契合 MySQL 单 Pod 独占挂载的需求,是块存储中间件持久化的首选方案。后续篇章中,Redis、MongoDB 等中间件同样会复用这一 StorageClass 体系。
七、下期预告
第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令)——将从 MySQL 的磁盘型持久化转向 Redis 的内存型缓存架构,讲解 Redis Cluster 分片原理、使用 bitnami/redis-cluster Helm Chart 部署 6 节点集群(3 主 3 从),以及 Ceph RBD 持久化 AOF/RDB 持久化文件的配置。敬请关注!
八、系列目录
- ✅ 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述
- ✅ 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战)
- ✅ 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优)
- 📌 第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检)(本文)
- 🔜 第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令)
- 🔜 第 6 天:K8s 部署 Redis Sentinel 哨兵模式(高可用架构 + 登录验证)
- 🔜 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检)
- 🔜 第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录)
- 🔜 第 9 天:K8s 部署 Nacos 注册配置中心(集群架构 + 登录巡检)
- 🔜 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令)
- 🔜 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检)
- 🔜 第 12 天:K8s 部署 Kafka 集群(Ceph RBD + 消息队列架构 + 运维)
- 🔜 第 13 天:K8s 部署 GitLab 代码托管平台(Ceph RBD 持久化 + 架构 + 巡检)
- 🔜 第 14 天:K8s 部署 ClickHouse 列式数据库集群(Ceph RBD + 架构设计)
- 🔜 第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景)

















暂无评论内容