别用 helm 装裸 mysql chart,真高可用必须用 mysql operator;helm 的 bitnami mysql chart 仅为单实例 statefulset 封装,无自动故障转移、组复制或 crd 管理能力,仅适用于开发测试。

直接上结论:别用 Helm 装裸 mysql chart,那只是单实例;真要高可用,必须用 MySQL Operator(比如 PressLabs 或 Bitnami 提供的),它才是能自动故障转移、管理组复制、声明式扩缩容的控制器。
为什么 Helm install mysql bitnami/mysql 不能算高可用
常见错误现象:kubectl get pods 只看到 1 个 mysql Pod,或手动改 replicas: 3 后出现复制中断、SHOW SLAVE STATUS 显示 Seconds_Behind_Master: NULL、主库挂了从库不自动升主。
根本原因:Bitnami 的 mysql chart 是面向单实例或简单主从的 StatefulSet 封装,它不监听 MysqlCluster 这类 CRD,没有内置 Orchestrator 组件,也不做 Raft 协调或 GTID 自动对齐。它只是“能跑 MySQL 的 Pod 模板”,不是“数据库集群操作系统”。
使用场景:适合开发/测试环境快速起一个带 PVC 的单节点 MySQL;不适合生产环境要求 RTO
关键区别:
-
mysqlchart → 输出StatefulSet+Service+Secret -
mysql-operatorchart → 输出CustomResourceDefinition+Deployment(Operator 控制器)+ClusterRoleBinding
部署 MySQL Operator 的最小可行路径
这不是“装个包就完事”的操作,Operator 是控制器,得先让它跑起来,再告诉它建什么集群。
实操建议:
- 添加 Helm 仓库时注意域名拼写:
helm repo add presslabs https://charts.presslabs.org(不是.com) - 安装 Operator 控制器本身,**不是数据库**:
helm install mysql-operator presslabs/mysql-operator --namespace=mysql-operator --create-namespace - 验证控制器就绪:
kubectl get pods -n mysql-operator -l app=mysql-operator,必须是Running状态,否则后续MysqlCluster创建会静默失败(无报错,但get mysqlclusters为空) - Operator 启动后,才真正开始监听自定义资源;此时你提交的
MysqlClusterYAML 才会被处理
示例片段(精简版):
apiVersion: mysql.presslabs.org/v1alpha1 kind: MysqlCluster metadata: name: prod-db spec: replicas: 3 secretName: mysql-creds backupSchedule: "0 2 * * *" backupURL: "s3://my-backup-bucket/"
注意:secretName 必须提前存在,且包含 rootPassword 和 replicationPassword 字段,Operator 不会帮你生成密码。
StatefulSet 手动搭主从的坑在哪
如果你跳过 Operator、坚持用原生 StatefulSet 实现主从,最容易卡在三个地方:
-
server-id 冲突:多个 Pod 若共用同一份 ConfigMap 中的
server-id=1,MySQL 启动直接拒绝(日志报Server id not set或复制报错ER_NET_PACKET_TOO_LARGE);必须用 initContainer 动态注入,如server-id=$((100 + $ordinal)) -
PVC 绑定漂移:用
hostPath或localPV 时,若没配nodeAffinity+volumeBindingMode: WaitForFirstConsumer,Pod 调度到其他节点会导致 PVC 处于Pending状态,集群起不来 - 读写分离失效:Service 类型若设为
ClusterIP且 selector 是app: mysql,流量会轮询打到所有 Pod,包括只读从库;必须拆成两个 Service:mysql(Headless,用于内部选主)和mysql-read(ClusterIP,selector 不含主库 label)
性能影响:手动主从无法自动检测脑裂,主库恢复后可能被误判为从库并尝试反向同步,引发数据覆盖;Operator 的 Orchestrator 组件会通过心跳+Raft 投票规避该问题。
Operator 部署后最常忽略的检查点
Operator 跑起来了、MysqlCluster 创建成功了、Pod 全 Running —— 这不等于高可用已生效。
务必确认以下几项:
-
kubectl get mysqlclusters.prod-db -o wide中STATUS字段是否为Running(不是Pending或空) -
kubectl logs -n mysql-operator deployment/mysql-operator | grep "reconciling"是否有持续日志输出,说明控制器在正常工作 - 进任意一个 Pod 执行
mysql -uroot -p -e "SELECT MEMBER_ROLE FROM performance_schema.replication_group_members;",应看到一个PRIMARY和多个SECONDARY - 手动删掉主 Pod:
kubectl delete pod prod-db-0,观察是否在 30 秒内出现新的PRIMARY,且prod-db-1或prod-db-2的状态变为Running并接管写入
最容易被忽略的是备份配置——backupURL 填错或权限不足时,Operator 不报错,但 backupSchedule 形同虚设;建议首次部署后立刻手动触发一次备份:kubectl exec -n mysql-operator deploy/mysql-operator -- mysqlctl backup create --cluster=prod-db。











