必须用StatefulSet,因其提供稳定Pod名称、网络标识和专属PVC绑定,避免Deployment导致的PVC错绑、GTID复制中断及CHANGE REPLICATION SOURCE失效;serviceName必须与Headless Service名一致以确保DNS解析正确生成mysql-0.mysql.default.svc.cluster.local等固定域名。

必须用 StatefulSet,不能用 Deployment 或 ReplicaSet;否则 Pod 重建后 PVC 错绑、GTID 复制中断、CHANGE REPLICATION SOURCE 指令失效——这不是调参能救的,是控制器语义错配。
为什么 serviceName 和 Headless Service 名字必须完全一致
StatefulSet 依赖 serviceName 字段去查找对应的 Headless Service,进而生成可解析的 DNS 名(如 mysql-0.mysql.default.svc.cluster.local)。名字不一致会导致:
-
PVC创建失败,Pod 卡在Pending状态,报错:no persistent volumes available for this claim - MySQL 启动时无法挂载
/var/lib/mysql,日志反复出现:Can't start server: Bind on unix socket - 从库执行
CHANGE REPLICATION SOURCE TO SOURCE_HOST='mysql-0'时解析失败,SHOW REPLICA STATUS\G显示IO_Running: No,错误信息为:error connecting to master
验证方式:kubectl exec -it mysql-0 -- nslookup mysql-0.mysql.default.svc.cluster.local。应返回唯一 IP;若报 NXDOMAIN 或返回多个 IP,说明 Service 未设为 headless 或名字不匹配。
volumeClaimTemplates 的命名和绑定逻辑
volumeClaimTemplates 不是“随便起个名”,它会按 name + - + StatefulSet name + - + ordinal 自动生成 PVC 名,例如:
metadata: name: data
→ 生成 data-mysql-0、data-mysql-1 等 PVC。
关键点:
- 每个 PVC 必须绑定独立 PV,不能共享;云厂商块存储(如 AWS EBS、阿里云
cloud_efficiency)默认绑定单可用区(AZ),跨 AZ 调度会导致 PVC Pending -
accessModes必须为["ReadWriteOnce"],MySQL 不支持多节点并发写入 -
storageClassName需显式指定,避免 fallback 到默认 StorageClass 导致行为不可控
如何让 mysql-0 固定为主库、其余为从库
StatefulSet 不内置角色调度,必须靠启动逻辑判断 $HOSTNAME(即 mysql-0、mysql-1):
- 主库(
mysql-0)需启用log-bin、固定server-id=1,且首次启动前必须执行RESET MASTER - 从库用动态
server-id,例如:server-id=$((100 + $(hostname | sed 's/mysql-//'))) - 从库启动前必须等待主库就绪:仅靠
readinessProbe不够,应在 entrypoint 脚本中用mysqladmin ping -h mysql-0.mysql.default.svc.cluster.local轮询,超时退出 - GTID 模式下,从库首次同步前需执行
SET GLOBAL gtid_purged = ''(前提是主库已RESET MASTER),否则START REPLICA报错
主库崩溃重建后复制链断裂怎么办
新 mysql-0 的 binlog position 和 GTID 已重置,旧从库直接 CHANGE REPLICATION SOURCE 会报:Could not find first log file name in binary log index file。
这不是配置遗漏,而是数据一致性边界问题:
- 生产环境必须配合备份恢复流程(如
mysqldump+mysqlbinlog定位位点),不能依赖自动重连 - 不能跳过 GTID 校验(
SET GLOBAL gtid_slave_skip_counter = 1)——这会破坏主从数据一致性 - InitContainer 中的初始化脚本必须区分“首次部署”和“重建场景”,对
mysql-0检查/var/lib/mysql/mysql目录是否存在,决定是否执行RESET MASTER
最易被忽略的一点:DNS 解析延迟和 CoreDNS 缓存可能导致从库在主库刚 ready 时仍连不上 mysql-0,建议在轮询逻辑里加入指数退避而非固定间隔。


















