必须显式设置architecture=replication、auth.rootPassword、primary/secondary.persistence.size及storageClass,否则无法生成主从资源、初始化失败或Pod Pending;验证需检查SHOW SLAVE STATUS中IO/SQL线程状态及Seconds_Behind_Master=0。

直接用 Helm 部署 MySQL 集群不是“一键安装就完事”,关键在于选对 Chart、配对参数、避开持久化和权限的坑。Bitnami 的 mysql Chart 是目前最稳定、文档最全、更新最勤的选项,比官方 mysql-operator 或 oracle/mysql-innodbcluster 更适合快速交付场景。
为什么优先选 bitnami/mysql 而不是 mysql-operator
bitnami/mysql 是纯 StatefulSet + Headless Service 架构,不依赖额外控制器,部署快、故障面小;而 mysql-operator 需要先装 Operator 控制器、再定义 CRD、再创建 MysqlCluster,调试链路长,出错时 kubectl get mysqlcluster 可能卡住或状态不刷新。另外,bitnami Chart 的 architecture 参数直接支持 replication(主从)和 standalone,无需手动写 binlog、change master 等配置。
常见错误现象包括:
-
mysqltest-primary-0Pod 一直CrashLoopBackOff,日志显示Can't start server: Bind on TCP/IP port: Address already in use—— 实际是primary.service.type=NodePort和secondary.service.type=NodePort冲突,两个服务抢同一个端口; - 从库连不上主库,报
ERROR 2003 (HY000): Can't connect to MySQL server—— 很可能是primary.service.clusterIP没设为None,导致 DNS 解析不到mysqltest-primary这个 headless 名; - Pod 重启后数据丢失 ——
persistence.enabled=false被误留,或storageClass不匹配底层 PV(比如用了nfs-mysql但集群没配这个 StorageClass)。
主从集群必须显式设置的 4 个参数
用 helm install 部署主从,光靠默认值不行,这四个键值必须明确覆盖:
-
architecture=replication:启用主从模式,否则默认是单节点standalone; -
auth.rootPassword:root 密码必须设,否则初始化失败(bitnami 镜像会拒绝空密码启动); -
primary.persistence.size和secondary.persistence.size:不能只设一个,否则从库 PVC 创建失败,报error validating data: ValidationError(PersistentVolumeClaim.spec): unknown field "size" in io.k8s.api.core.v1.PersistentVolumeClaimSpec; -
global.storageClass或分别指定primary.persistence.storageClass/secondary.persistence.storageClass:K8s 1.20+ 默认不提供defaultStorageClass,不填就卡在Pending状态。
示例命令:
helm install mysql-prod bitnami/mysql \ --set architecture=replication \ --set auth.rootPassword=prod123! \ --set primary.persistence.size=20Gi \ --set secondary.persistence.size=20Gi \ --set primary.persistence.storageClass=nfs-sc \ --set secondary.persistence.storageClass=nfs-sc \ --set primary.service.type=ClusterIP \ --set secondary.service.type=ClusterIP
如何验证主从是否真正同步
别只看 kubectl get pods 全是 Running 就以为 OK。真实同步需进容器确认:
- 连主库执行
SHOW MASTER STATUS;,记下File和Position; - 连从库执行
SHOW SLAVE STATUS\G,重点检查:
–Slave_IO_Running: Yes
–Slave_SQL_Running: Yes
–Seconds_Behind_Master: 0(非NULL); - 主库建表插入数据后,立刻在从库查同一张表 —— 不要等 30 秒,有些环境因网络或 clock skew 会导致延迟突增;
- 注意 bitnami 镜像默认开启
skip-name-resolve,所以从库CHANGE MASTER TO里的MASTER_HOST必须填mysql-prod-primary(Service 名),不能填 Pod IP。
升级与回滚时最容易被忽略的点
Helm 升级 MySQL 版本(比如从 8.0.33 到 8.0.35)看似简单,但有两处硬约束:
- MySQL 主版本号变更(如 8.x → 9.x)不支持原地升级,
helm upgrade会失败并提示incompatible version,必须先helm uninstall再重装,且需提前备份数据; - 修改
auth.rootPassword后执行helm upgrade,旧密码仍有效,新密码只对新建连接生效 —— 因为 bitnami 的 initContainer 不会自动执行ALTER USER,得手动进容器改; -
values.yaml里如果写了primary.extraEnvVars,升级时若漏掉该字段,Helm 会清空原有环境变量(不是 merge),导致 TZ 或 custom config 丢失。
真正稳的交付节奏是:每次变更前先 helm get values mysql-prod > values-backup.yaml,改完再 diff,避免隐性覆盖。


















