Kubernetes StatefulSet 部署 MySQL 集群

1. Headless Service 配置

Headless Service 为 StatefulSet 提供稳定的网络标识,实现 Pod 直接通信:

apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  clusterIP: None  # 定义Headless Service
  ports:
  - port: 3306
    name: mysql
  selector:
    app: mysql
  publishNotReadyAddresses: true  # 允许访问未就绪Pod

关键特性:

  • DNS 解析格式:<pod-name>.<service-name>.<namespace>.svc.cluster.local
  • 每个 Pod 获得独立 DNS 记录(如 mysql-0.mysql-headless.default.svc
  • 支持 Pod 间直接通信,规避负载均衡
2. PVC 动态绑定

StatefulSet 通过 volumeClaimTemplates 实现持久化存储:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-headless
  replicas: 3
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard"  # 动态存储类
      resources:
        requests:
          storage: 10Gi
  template:
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql

存储特性:

  • 自动创建 PVC:mysql-data-mysql-0, mysql-data-mysql-1, ...
  • Pod 重建时自动绑定原 PVC
  • 存储类需支持动态卷供应(如 Rook, Ceph, AWS EBS)
3. 主从同步实现

通过 Pod 索引区分主从节点:

env:
- name: POD_INDEX
  valueFrom:
    fieldRef:
      fieldPath: metadata.name  # 获取Pod名称(如mysql-0)

初始化脚本逻辑(容器启动时执行):

#!/bin/bash
# 提取Pod序号
ordinal=${HOSTNAME##*-}

if [[ $ordinal -eq 0 ]]; then
  # 主节点配置
  echo "Configuring PRIMARY node"
  cat > /etc/mysql/conf.d/server-id.cnf <<EOF
[mysqld]
server_id=1
log-bin=mysql-bin
innodb_flush_log_at_trx_commit=1
sync_binlog=1
EOF
else
  # 从节点配置
  echo "Configuring REPLICA node"
  cat > /etc/mysql/conf.d/server-id.cnf <<EOF
[mysqld]
server_id=$((ordinal + 10))  # 确保ID唯一
relay-log=mysql-relay-bin
read_only=1
EOF
  # 等待主节点就绪
  until nslookup mysql-0.mysql-headless; do sleep 2; done
  # 建立复制链路
  mysql -u root -p$MYSQL_ROOT_PASSWORD <<SQL
CHANGE MASTER TO
  MASTER_HOST='mysql-0.mysql-headless',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl-password',
  MASTER_AUTO_POSITION=1;
START SLAVE;
SQL
fi

完整架构图
graph TD
  subgraph StatefulSet
    A[mysql-0] -->|Headless DNS| B[mysql-1]
    A -->|Headless DNS| C[mysql-2]
    A -->|Primary| D[(PVC-0)]
    B -->|Replica| E[(PVC-1)]
    C -->|Replica| F[(PVC-2)]
  end
  G[Headless Service] -.-> A
  G -.-> B
  G -.-> C

关键注意事项
  1. 数据持久化:确保 innodb_log_file_size 匹配 PVC 大小
  2. 故障恢复
    • 主节点故障时手动切换:mysql-0 重建后需重新配置复制
    • 建议使用 kubectl exec 执行 SHOW SLAVE STATUS
  3. 安全配置
    • 通过 Secret 管理密码:
      env:
      - name: MYSQL_ROOT_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysql-secrets
            key: root-password
      

    • 创建复制专用账户
  4. 扩展性:添加副本时,新 Pod 自动从主节点同步数据

此方案实现 MySQL 集群的稳定部署,需根据实际环境调整存储类、资源配置和同步参数。

更多推荐