Helm 安装 MySQL 集群
用 Helm 快速部署带复制的 MySQL。
Helm 能把复杂的 YAML 打包成 Chart,适合快速部署数据库组件。Bitnami 的 MySQL Chart 提供现成的主从复制拓扑,让你不用手写大量 StatefulSet 与 Service,就能快速落地一个可用的 MySQL 集群。
下面在原有的快速安装基础上补充了命名空间、凭据设置、values 配置、连通性验证、复制验证与常见排查步骤,帮助你形成完整的实践闭环。
预备条件
- 集群存在可用的默认 StorageClass。
- 本地已安装
helm与kubectl。 - 资源建议:至少 2-4GB 内存用于主库 + 从库。
创建命名空间
把数据库与业务隔离:
kubectl create namespace db
安装 Chart(主从复制)
添加 Bitnami 仓库并启用 replication:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install mysql bitnami/mysql \
--namespace db \
--set architecture=replication \
--set auth.rootPassword='ChangeMe123!' \
--set primary.persistence.size=10Gi \
--set secondary.replicaCount=1
也可以使用 values.yaml 统一管理配置:
architecture: replication
auth:
rootPassword: "ChangeMe123!"
username: "app"
password: "AppPassword123!"
database: "appdb"
primary:
persistence:
size: 10Gi
secondary:
replicaCount: 1
应用配置:
helm install mysql bitnami/mysql -n db -f values.yaml
常用 Helm 命令
helm list -n db
helm status mysql -n db
helm get values mysql -n db
helm upgrade mysql -n db -f values.yaml
helm rollback mysql -n db 1
验证 Pod 与 Service
kubectl get pods -n db
kubectl get svc -n db
你应该能看到主库与从库 Pod,以及分别用于写入和读取的 Service。
使用临时客户端验证
启动一个临时 MySQL 客户端 Pod:
kubectl run -it --rm mysql-client \
--namespace db \
--image=bitnami/mysql:8.0 \
--command -- bash
进入后连接主库:
mysql -h mysql-primary.db.svc.cluster.local -u root -p
创建数据并写入:
CREATE DATABASE IF NOT EXISTS demo;
USE demo;
CREATE TABLE items (id INT PRIMARY KEY, name VARCHAR(64));
INSERT INTO items VALUES (1, 'hello');
再查询从库验证复制:
mysql -h mysql-secondary.db.svc.cluster.local -u root -p -e "SELECT * FROM demo.items;"
读写分离
主库用于写入,从库用于读。应用可以配置两个连接地址:
MYSQL_WRITE_HOST=mysql-primary.db.svc.cluster.localMYSQL_READ_HOST=mysql-secondary.db.svc.cluster.local
不确定时先只用主库,稳定后再把只读流量迁移到从库。
资源请求与限制
数据库对 CPU 与 IO 较敏感,建议设置 requests/limits:
primary:
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
secondary:
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
容量与性能预期
数据库的瓶颈常常在磁盘 IO 和连接数上。即便 CPU 看起来足够,磁盘性能不足也会导致复制延迟和查询抖动。建议预留一定磁盘空间,并监控磁盘使用率,避免写满导致服务异常。
如果业务读写量增长明显,优先扩容从库并观察效果,再考虑提升主库规格。
初始化脚本
可用 initdbScripts 在首次启动时创建表:
initdbScripts:
00-schema.sql: |
CREATE DATABASE IF NOT EXISTS appdb;
USE appdb;
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(128) NOT NULL
);
配置覆盖
需要调整 MySQL 参数时可以在 values 中覆盖:
primary:
configuration: |-
[mysqld]
max_connections=500
slow_query_log=1
long_query_time=1
修改后执行 helm upgrade 让配置生效。
扩容从库
增加读能力时可以扩容从库:
helm upgrade mysql bitnami/mysql -n db --set secondary.replicaCount=3
监控基础
有 Prometheus 时可以开启指标:
helm upgrade mysql bitnami/mysql -n db --set metrics.enabled=true
关注查询延迟、复制延迟与磁盘剩余空间。
密钥管理
避免把密码直接写在命令行,可先创建 Secret:
kubectl -n db create secret generic mysql-auth \
--from-literal=root-password='ChangeMe123!' \
--from-literal=password='AppPassword123!'
然后在 values 中引用:
auth:
existingSecret: mysql-auth
username: app
database: appdb
服务访问方式
生产环境通常保持数据库内网访问。若需要临时外部访问,优先使用端口转发:
kubectl port-forward -n db svc/mysql-primary 3306:3306
然后用本地客户端连接:
mysql -h 127.0.0.1 -P 3306 -u root -p
用户权限建议
应用程序不要使用 root 账号,建议创建最小权限用户,并只授予必要库的权限。定期轮换密码,避免长期固定凭据。
网络策略(可选)
若集群启用 NetworkPolicy,可限制只有应用命名空间能访问:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app
namespace: db
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: mysql
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: app
ports:
- protocol: TCP
port: 3306
运维流程建议
建议维护一个简单的 runbook:
- 定期检查 Pod 重启次数与 PVC 使用率。
- 在测试环境演练一次恢复流程。
- 升级 chart 前固定版本并阅读变更说明。
备份与升级建议
即便是快速部署,也要尽早明确备份方案。最简单的方法是定期执行逻辑备份并保存到对象存储或安全位置。Chart 升级前务必阅读发行说明,并在测试环境验证升级路径。
复制排查
如果从库延迟升高,先检查 CPU/磁盘 IO 与网络。也可以查看主从状态:
kubectl exec -n db mysql-primary-0 -- mysql -u root -p -e "SHOW MASTER STATUS\\G"
kubectl exec -n db mysql-secondary-0 -- mysql -u root -p -e "SHOW SLAVE STATUS\\G"
常见问题
- Pod Pending:PVC 未绑定或缺少 StorageClass。
- CrashLoopBackOff:密码配置错误或内存不足。
- 复制延迟:CPU/磁盘 IO 竞争导致从库同步变慢。
快速排查:
kubectl describe pod -n db <pod-name>
kubectl logs -n db <pod-name>
实操要点
- 先做快速盘点:
kubectl get nodes、kubectl get pods -A、kubectl get events -A。 - 对比“期望状态”和“实际状态”,
kubectl describe往往能解释漂移或失败原因。 - 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。
快速检查清单
- 资源定义与业务意图一致。
- Namespace、权限、镜像与环境匹配。
- 上线前具备健康探针与可观测日志。
- 备份与恢复流程有记录。