大连全瓷种植牙齿制作中心 发表于 2025-3-9 01:32:16

基于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: |
   
    log-bin=mysql-bin
    server-id=1
slave.cnf: |
   
    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` =~ -(+)$ ]] || exit 1
          ordinal=${BASH_REMATCH}
          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)
Client -> Service(mysql-slave)-> Pod(mysql-1, mysql-2)
可根据需求调解副本数目或增加读写分离中间件(如ProxySQL)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 基于Kubernetes部署MySQL主从集群