1. 为什么需要这种组合?
想象一下这样的场景:你的电商平台在"双十一"凌晨突然数据库宕机,所有交易数据丢失,同时每秒有上万用户无法提交订单。这正是需要MySQL主从架构提供实时数据冗余,而Kubernetes的StatefulSet能保证数据库实例永远在线的根本原因。这种组合就像给数据库上了双重保险,既满足业务高可用需求,又符合云原生时代的部署规范。
2. 基础环境准备
2.1 示例使用的技术栈
# 版本声明(置于首个代码块顶部)
# Kubernetes v1.25+
# Docker 20.10+
# MySQL 8.0.30+
# 存储类:rook-cephfs (生产推荐) 或 hostPath (测试使用)
2.2 创建专属命名空间
apiVersion: v1
kind: Namespace
metadata:
name: db-prod
labels:
tier: database
3. StatefulSet核心配置解剖
3.1 主从架构设计蓝图
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-cluster
namespace: db-prod
spec:
serviceName: "mysql-svc"
replicas: 3 # 1主2从
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
# 设置初始化容器处理主从配置
initContainers:
- name: init-mysql
image: mysql:8.0
command: ["bash", "/init/init.sh"]
volumeMounts:
- name: init-script
mountPath: /init
# 主要容器配置
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: rootPassword
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
# 重要健康检查配置
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-uroot", "-p$(MYSQL_ROOT_PASSWORD)"]
initialDelaySeconds: 30
periodSeconds: 10
volumes:
- name: init-script
configMap:
name: mysql-init-script
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "rook-cephfs"
resources:
requests:
storage: 50Gi
3.2 主从初始化关键脚本
#!/bin/bash
# 存放于ConfigMap中的初始化脚本
set -ex
# 获取Pod索引编号(StatefulSet核心特性)
HOSTNAME=$(hostname -s)
INDEX=${HOSTNAME##*-}
# 主节点处理逻辑
if [ $INDEX -eq 0 ]; then
echo "正在初始化主库..."
# 生成主库专用配置文件
cat > /etc/mysql/conf.d/master.cnf <<EOF
[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
EOF
# 从节点处理逻辑
else
echo "正在配置第${INDEX}个从库"
# 获取主库IP(通过Headless Service)
MASTER_HOST=$(dig mysql-svc-0.mysql-svc.db-prod.svc.cluster.local +short)
# 生成从库配置文件
cat > /etc/mysql/conf.d/slave.cnf <<EOF
[mysqld]
server-id=$((INDEX+1))
relay-log=mysql-relay
read_only=1
super_read_only=1
EOF
# 等待主库就绪
until mysql -h ${MASTER_HOST} -uroot -p${MYSQL_ROOT_PASSWORD} -e 'SELECT 1'; do
echo "等待主库响应..."
sleep 5
done
# 配置主从复制
mysql -uroot -p${MYSQL_ROOT_PASSWORD} <<SQL
CHANGE MASTER TO
MASTER_HOST='${MASTER_HOST}',
MASTER_USER='repl',
MASTER_PASSWORD='${REPLICATION_PASSWORD}',
MASTER_AUTO_POSITION=1;
START SLAVE;
SQL
fi
4. 配套服务的艺术
4.1 Headless Service设计
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
namespace: db-prod
spec:
clusterIP: None # 关键设置!
selector:
app: mysql
ports:
- name: mysql
port: 3306
4.2 外部访问网关(可选)
apiVersion: v1
kind: Service
metadata:
name: mysql-proxy
spec:
type: LoadBalancer
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
5. 你必须知道的技术细节
5.1 网络标识的稳定性奥秘
每个Pod会获得固定DNS名称:
mysql-cluster-0.mysql-svc.db-prod.svc.cluster.local
mysql-cluster-1.mysql-svc.db-prod.svc.cluster.local
mysql-cluster-2.mysql-svc.db-prod.svc.cluster.local
这种命名规则意味着:
- 重启Pod不会改变DNS地址
- 可以精确指定连接到主节点(索引为0的Pod)
- 应用代码可以直接引用固定域名
5.2 数据持久化精要
存储配置采用了volumeClaimTemplates
,它具备以下特性:
- 每个Pod自动创建独立的PVC
- PVC命名规则:
<volumeClaimTemplateName>-<statefulsetName>-<ordinal>
- 支持动态卷供应(需预配StorageClass)
- 数据卷与Pod实例生命周期解耦
6. 技术优势与限制
6.1 三大核心优势
- 有序部署:确保主节点(编号0)先启动完成
- 稳定网络标识:应用程序无需处理IP变动
- 自动故障转移:Pod故障后自动重建并挂载原数据卷
6.2 当前方案的局限性
- 主节点故障需手工切换(可配合Kubernetes Operator解决)
- 原生方案不处理数据备份(需结合Velero等工具)
- 批量写入性能受限于存储方案
7. 典型应用场景
7.1 最适配的用例
- 需要事务支持的电商订单系统
- 金融交易流水记录系统
- 在线教育平台的课程信息管理
- 社交平台的用户关系数据存储
7.2 不推荐场景
- 临时测试环境(可用Deployment简化部署)
- PB级时序数据存储(考虑专用时序数据库)
- 需要多主架构的场景(需使用Galera Cluster)
8. 部署注意事项
8.1 存储选择金标准
- 生产环境必须使用支持RWO的存储类
- 推荐:Ceph RBD、Portworx、Local PV
- 避免:hostPath(无法保证数据持久性)
8.2 安全配置要点
# Secret创建示例(需提前准备)
apiVersion: v1
kind: Secret
metadata:
name: mysql-secrets
type: Opaque
data:
rootPassword: BASE64编码值
replicationPassword: BASE64编码值
8.3 监控方案搭配
推荐组合:
- Prometheus + mysqld_exporter
- 自定义Kubernetes事件监控
- 慢查询日志分析(需挂载额外卷)
9. 故障排查指南
9.1 常见问题速查表
现象 | 检查方向 | 诊断命令 |
---|---|---|
从库不同步 | 主从连接状态 | SHOW SLAVE STATUS\G |
Pod启动失败 | 存储卷状态 | kubectl describe pvc |
主节点失联 | DNS解析检查 | nslookup mysql-svc-0.mysql-svc |
性能瓶颈 | 资源使用率 | kubectl top pod |
9.2 关键日志查看
# 查看指定Pod的初始化日志
kubectl logs mysql-cluster-0 -c init-mysql
# 实时追踪主节点日志
kubectl logs -f mysql-cluster-0 --tail=100
10. 总结与展望
通过本文的实践,我们已经完整实现了:
- 基于StatefulSet的自动编排主从架构
- 稳定的网络标识与存储配置
- 生产级的安全加固方案
- 完整的监控与排错体系
未来的演进方向可能包括:
- 结合Operator实现自动故障转移
- 集成多活架构扩展写能力
- 智能查询路由中间件的集成