基于Kubernetes部署MySQL主从集群

打印 上一主题 下一主题

主题 962|帖子 962|积分 2901

以下是一个基于Kubernetes部署MySQL主从集群的具体YAML示例,包罗StatefulSet、Service、ConfigMap和Secret等关键配置。MySQL主从集群需要至少1个主节点和多个从节点,这里使用 StatefulSet + 初始化脚本 实现主从自动配置。

1. 创建 Namespace (可选)

  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4.   name: mysql-cluster
复制代码

2. 创建 Secret (存储MySQL暗码)

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4.   name: mysql-secrets
  5.   namespace: mysql-cluster
  6. type: Opaque
  7. data:
  8.   root-password: eHg=  # echo -n "xx" | base64 (示例密码)
  9.   replication-password: eHg=  # 主从同步专用密码
复制代码

3. 创建 ConfigMap (主从配置文件)

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4.   name: mysql-config
  5.   namespace: mysql-cluster
  6. data:
  7.   master.cnf: |
  8.     [mysqld]
  9.     log-bin=mysql-bin
  10.     server-id=1
  11.   slave.cnf: |
  12.     [mysqld]
  13.     log-bin=mysql-bin
  14.     server-id=2
  15.   init.sql: |  # 初始化主从复制的SQL脚本
  16.     CREATE USER 'repl'@'%' IDENTIFIED BY 'xx';  # 密码需与Secret中一致
  17.     GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
  18.     FLUSH PRIVILEGES;
复制代码

4. 创建 Service (主从分离访问)

  1. # 主节点服务
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5.   name: mysql-master
  6.   namespace: mysql-cluster
  7. spec:
  8.   ports:
  9.   - name: mysql
  10.     port: 3306
  11.   selector:
  12.     app: mysql
  13.     role: master
  14.   clusterIP: None
  15. # 从节点服务
  16. apiVersion: v1
  17. kind: Service
  18. metadata:
  19.   name: mysql-slave
  20.   namespace: mysql-cluster
  21. spec:
  22.   ports:
  23.   - name: mysql
  24.     port: 3306
  25.   selector:
  26.     app: mysql
  27.     role: slave
  28.   clusterIP: None
复制代码

5. 创建 StatefulSet (1主2从)

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4.   name: mysql
  5.   namespace: mysql-cluster
  6. spec:
  7.   serviceName: mysql
  8.   replicas: 3
  9.   selector:
  10.     matchLabels:
  11.       app: mysql
  12.   template:
  13.     metadata:
  14.       labels:
  15.         app: mysql
  16.         role: slave  # 默认标记为slave,init容器中将修改第一个Pod为master
  17.     spec:
  18.       initContainers:
  19.       - name: init-mysql
  20.         image: mysql:8.0
  21.         command:
  22.         - bash
  23.         - "-c"
  24.         - |
  25.           # 根据Pod序号分配server-id和角色
  26.           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
  27.           ordinal=${BASH_REMATCH[1]}
  28.           if [[ $ordinal -eq 0 ]]; then
  29.             # 主节点配置
  30.             cp /mnt/config/master.cnf /mnt/conf.d/
  31.             echo "role=master" > /mnt/conf.d/role
  32.           else
  33.             # 从节点配置
  34.             cp /mnt/config/slave.cnf /mnt/conf.d/
  35.             echo "role=slave" > /mnt/conf.d/role
  36.           fi
  37.         volumeMounts:
  38.         - name: conf
  39.           mountPath: /mnt/conf.d
  40.         - name: config-map
  41.           mountPath: /mnt/config
  42.       - name: clone-mysql
  43.         image: alpine:3.18
  44.         command:
  45.         - bash
  46.         - "-c"
  47.         - |
  48.           # 只有从节点需要等待主节点初始化完成
  49.           if [ -f /mnt/conf.d/role ] && grep -q "slave" /mnt/conf.d/role; then
  50.             until nslookup mysql-0.mysql; do
  51.               sleep 2
  52.             done
  53.           fi
  54.         volumeMounts:
  55.         - name: conf
  56.           mountPath: /mnt/conf.d
  57.       containers:
  58.       - name: mysql
  59.         image: mysql:8.0
  60.         env:
  61.         - name: MYSQL_ROOT_PASSWORD
  62.           valueFrom:
  63.             secretKeyRef:
  64.               name: mysql-secrets
  65.               key: root-password
  66.         - name: MYSQL_REPL_PASSWORD
  67.           valueFrom:
  68.             secretKeyRef:
  69.               name: mysql-secrets
  70.               key: replication-password
  71.         ports:
  72.         - name: mysql
  73.           containerPort: 3306
  74.         volumeMounts:
  75.         - name: data
  76.           mountPath: /var/lib/mysql
  77.         - name: conf
  78.           mountPath: /etc/mysql/conf.d
  79.         - name: init-sql
  80.           mountPath: /docker-entrypoint-initdb.d
  81.         livenessProbe:
  82.           exec:
  83.             command: ["mysqladmin", "ping", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
  84.           initialDelaySeconds: 30
  85.           periodSeconds: 10
  86.         readinessProbe:
  87.           exec:
  88.             command: ["mysql", "-uroot", "-p${MYSQL_ROOT_PASSWORD}", "-e", "SELECT 1"]
  89.           initialDelaySeconds: 5
  90.           periodSeconds: 5
  91.       volumes:
  92.       - name: conf
  93.         emptyDir: {}
  94.       - name: config-map
  95.         configMap:
  96.           name: mysql-config
  97.           items:
  98.           - key: master.cnf
  99.             path: master.cnf
  100.           - key: slave.cnf
  101.             path: slave.cnf
  102.       - name: init-sql
  103.         configMap:
  104.           name: mysql-config
  105.           items:
  106.           - key: init.sql
  107.             path: init.sql
  108.   volumeClaimTemplates:
  109.   - metadata:
  110.       name: data
  111.     spec:
  112.       accessModes: ["ReadWriteOnce"]
  113.       storageClassName: "standard"  # 根据环境调整
  114.       resources:
  115.         requests:
  116.           storage: 10Gi
复制代码

6. 主从初始化自动化脚本 (StatefulSet启动后执行)

主节点启动后自动创建复制用户,从节点自动毗连主节点:
  1. # 在StatefulSet的Pod模板中添加以下生命周期钩子
  2. lifecycle:
  3.   postStart:
  4.     exec:
  5.       command:
  6.       - "/bin/bash"
  7.       - "-c"
  8.       - |
  9.         if [ -f /etc/mysql/conf.d/role ] && grep -q "master" /etc/mysql/conf.d/role; then
  10.           # 主节点执行初始化SQL
  11.           mysql -uroot -p${MYSQL_ROOT_PASSWORD} < /docker-entrypoint-initdb.d/init.sql
  12.         else
  13.           # 从节点配置主从复制
  14.           until mysql -h mysql-0.mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"; do
  15.             sleep 1
  16.           done
  17.           mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "
  18.             CHANGE MASTER TO
  19.             MASTER_HOST='mysql-0.mysql',
  20.             MASTER_USER='repl',
  21.             MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',
  22.             MASTER_AUTO_POSITION=1;
  23.             START SLAVE;
  24.           "
  25.         fi
复制代码

验证主从同步

  1. # 检查主节点状态
  2. kubectl exec -it mysql-0 -n mysql-cluster -- mysql -uroot -p -e "SHOW MASTER STATUS\G"
  3. # 检查从节点同步状态
  4. kubectl exec -it mysql-1 -n mysql-cluster -- mysql -uroot -p -e "SHOW SLAVE STATUS\G"
复制代码

关键注意事项:


  • 主节点高可用:此方案主节点单点,若需高可用,需联合 OrchestratorProxySQL 实现故障转移。
  • 数据持久化:确保 storageClassName 与实际存储体系匹配(如 rook-cephfs、nfs)。
  • 暗码安全:通过Secret管理敏感信息,禁止明文存储。
  • 网络通讯:确保StatefulSet的Pod之间可通过DNS名称互相访问(如 mysql-0.mysql.mysql-cluster.svc.cluster.local)。
  • 扩展性:通过增加 replicas 数目扩展从节点。

完整架构示意图:

  1. Client -> Service(mysql-master) -> Pod(mysql-0) [Master]
  2. Client -> Service(mysql-slave)  -> Pod(mysql-1, mysql-2) [Slave]
复制代码
可根据需求调解副本数目或增加读写分离中间件(如ProxySQL)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表