基于Kubernetes部署MySQL主从集群
目录
基于Kubernetes部署MySQL主从集群
以下是一个基于Kubernetes部署MySQL主从集群的详细YAML示例,包含StatefulSet、Service、ConfigMap和Secret等关键配置。MySQL主从集群需要至少1个主节点和多个从节点,这里使用 StatefulSet + 初始化脚本 实现主从自动配置。
1. 创建 Namespace (可选)
apiVersion: v1
kind: Namespace
metadata:
name: mysql-cluster
2. 创建 Secret (存储MySQL密码)
apiVersion: v1
kind: Secret
metadata:
name: mysql-secrets
namespace: mysql-cluster
type: Opaque
data:
root-password: eHg= # echo -n "xx" | base64 (示例密码)
replication-password: eHg= # 主从同步专用密码
3. 创建 ConfigMap (主从配置文件)
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: mysql-cluster
data:
master.cnf: |
[mysqld]
log-bin=mysql-bin
server-id=1
slave.cnf: |
[mysqld]
log-bin=mysql-bin
server-id=2
init.sql: | # 初始化主从复制的SQL脚本
CREATE USER 'repl'@'%' IDENTIFIED BY 'xx'; # 密码需与Secret中一致
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
4. 创建 Service (主从分离访问)
# 主节点服务
apiVersion: v1
kind: Service
metadata:
name: mysql-master
namespace: mysql-cluster
spec:
ports:
- name: mysql
port: 3306
selector:
app: mysql
role: master
clusterIP: None
# 从节点服务
apiVersion: v1
kind: Service
metadata:
name: mysql-slave
namespace: mysql-cluster
spec:
ports:
- name: mysql
port: 3306
selector:
app: mysql
role: slave
clusterIP: None
5. 创建 StatefulSet (1主2从)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: mysql-cluster
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
role: slave # 默认标记为slave,init容器中将修改第一个Pod为master
spec:
initContainers:
- name: init-mysql
image: mysql:8.0
command:
- bash
- "-c"
- |
# 根据Pod序号分配server-id和角色
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
if [[ $ordinal -eq 0 ]]; then
# 主节点配置
cp /mnt/config/master.cnf /mnt/conf.d/
echo "role=master" > /mnt/conf.d/role
else
# 从节点配置
cp /mnt/config/slave.cnf /mnt/conf.d/
echo "role=slave" > /mnt/conf.d/role
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: config-map
mountPath: /mnt/config
- name: clone-mysql
image: alpine:3.18
command:
- bash
- "-c"
- |
# 只有从节点需要等待主节点初始化完成
if [ -f /mnt/conf.d/role ] && grep -q "slave" /mnt/conf.d/role; then
until nslookup mysql-0.mysql; do
sleep 2
done
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: root-password
- name: MYSQL_REPL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: replication-password
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: conf
mountPath: /etc/mysql/conf.d
- name: init-sql
mountPath: /docker-entrypoint-initdb.d
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command: ["mysql", "-uroot", "-p${MYSQL_ROOT_PASSWORD}", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: conf
emptyDir: {}
- name: config-map
configMap:
name: mysql-config
items:
- key: master.cnf
path: master.cnf
- key: slave.cnf
path: slave.cnf
- name: init-sql
configMap:
name: mysql-config
items:
- key: init.sql
path: init.sql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard" # 根据环境调整
resources:
requests:
storage: 10Gi
6. 主从初始化自动化脚本 (StatefulSet启动后执行)
主节点启动后自动创建复制用户,从节点自动连接主节点:
# 在StatefulSet的Pod模板中添加以下生命周期钩子
lifecycle:
postStart:
exec:
command:
- "/bin/bash"
- "-c"
- |
if [ -f /etc/mysql/conf.d/role ] && grep -q "master" /etc/mysql/conf.d/role; then
# 主节点执行初始化SQL
mysql -uroot -p${MYSQL_ROOT_PASSWORD} < /docker-entrypoint-initdb.d/init.sql
else
# 从节点配置主从复制
until mysql -h mysql-0.mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"; do
sleep 1
done
mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "
CHANGE MASTER TO
MASTER_HOST='mysql-0.mysql',
MASTER_USER='repl',
MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
MASTER_AUTO_POSITION=1;
START SLAVE;
"
fi
验证主从同步
# 检查主节点状态
kubectl exec -it mysql-0 -n mysql-cluster -- mysql -uroot -p -e "SHOW MASTER STATUS\G"
# 检查从节点同步状态
kubectl exec -it mysql-1 -n mysql-cluster -- mysql -uroot -p -e "SHOW SLAVE STATUS\G"
关键注意事项:
- 主节点高可用 :此方案主节点单点,若需高可用,需结合 Orchestrator 或 ProxySQL 实现故障转移。
- 数据持久化
:确保
storageClassName
与实际存储系统匹配(如rook-cephfs
、nfs
)。 - 密码安全 :通过Secret管理敏感信息,禁止明文存储。
- 网络通信
:确保StatefulSet的Pod之间可通过DNS名称互相访问(如
mysql-0.mysql.mysql-cluster.svc.cluster.local
)。 - 扩展性
:通过增加
replicas
数量扩展从节点。
完整架构示意图:
Client -> Service(mysql-master) -> Pod(mysql-0) [Master]
Client -> Service(mysql-slave) -> Pod(mysql-1, mysql-2) [Slave]
可根据需求调整副本数量或增加读写分离中间件(如ProxySQL)。