目录

K8S中MySQL配置持久化存储

K8S中MySQL配置持久化存储

在 Kubernetes 中为有状态应用(如 MySQL)配置持久化存储,需结合 StatefulSetPersistentVolumeClaim (PVC)StorageClass ,确保数据在 Pod 重启或迁移时不会丢失。以下是详细步骤和最佳实践:


一、核心组件选择

组件作用
StatefulSet为每个 Pod 提供唯一的网络标识和稳定的持久化存储(按顺序创建/删除)。
PVC声明 Pod 所需的存储容量和访问模式(如 ReadWriteOnce )。
StorageClass定义动态创建 PV 的规则(如云厂商存储类型、回收策略)。

二、配置步骤(以 MySQL 为例)

1. 创建 StorageClass(可选,若需动态供应)

如果是云环境(如 AWS、GCP),通常已有默认 StorageClass。若需自定义(例如本地存储),需手动配置:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mysql-storage
provisioner: kubernetes.io/aws-ebs  # 根据环境调整(如 rook-ceph、local)
parameters:
  type: gp3                         # AWS EBS 类型(或 SSD、HDD)
reclaimPolicy: Retain               # 删除 PVC 后保留 PV 和数据
volumeBindingMode: WaitForFirstConsumer  # 延迟绑定到 Pod 调度节点
2. 定义 StatefulSet 和 PVC 模板
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-headless     # Headless Service 用于 Pod 发现
  replicas: 1                     # 单节点示例(生产环境建议集群化)
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "your-root-password"
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql  # MySQL 数据目录
  volumeClaimTemplates:           # 自动为每个 Pod 创建 PVC
    - metadata:
        name: mysql-data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: mysql-storage  # 使用自定义 StorageClass
        resources:
          requests:
            storage: 20Gi               # 根据需求调整容量
3. 创建 Headless Service
apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  clusterIP: None   # Headless Service 无 ClusterIP
  selector:
    app: mysql
  ports:
    - port: 3306

三、关键配置说明

1. 存储访问模式 ( accessModes )
  • ReadWriteOnce (RWO) :单节点读写(适合单实例 MySQL)。
  • ReadWriteMany (RWX) :多节点读写(适用于分布式数据库如 Cassandra)。
  • ReadOnlyMany (ROX) :多节点只读。
2. 持久化路径
  • MySQL 默认数据目录为 /var/lib/mysql ,必须挂载到持久化卷。
  • 挂载其他路径(如配置文件)需额外配置。
3. 动态供应 vs 静态供应
  • 动态供应 (推荐):通过 StorageClass 自动创建 PV。
  • 静态供应 :手动创建 PV 并绑定 PVC(适合本地存储或无云厂商环境)。

四、生产环境优化

1. 高可用配置
  • MySQL 集群 :使用 Galera Cluster 或 Group Replication,配合多副本 StatefulSet。
  • 跨可用区存储 :配置 StorageClass 支持多 AZ(如 AWS EBS 需结合 topologyKey: topology.kubernetes.io/zone )。
2. 备份与恢复
  • 定期快照 :使用云厂商快照工具(如 AWS EBS Snapshot)或 Velero。
  • 逻辑备份 :通过 CronJob 执行 mysqldump 并存储到对象存储(如 S3)。
3. 监控与告警
  • 监控 PV/PVC 使用率(Prometheus + kubelet 指标)。
  • 设置 PVC 容量不足的告警规则。

五、验证流程

  1. 部署验证

    kubectl apply -f mysql-statefulset.yaml
    kubectl get statefulset,pvc,pod -l app=mysql
    • 确认 PVC 状态为 Bound ,Pod 运行正常。
  2. 数据持久化测试

    • 进入 MySQL Pod 写入测试数据:

      kubectl exec -it mysql-0 -- mysql -u root -p
      CREATE DATABASE test;
    • 删除 Pod 并观察 StatefulSet 自动重建:

      kubectl delete pod mysql-0
      kubectl exec -it mysql-0 -- mysql -u root -p -e "SHOW DATABASES;"  # 确认 test 库存在
  3. 故障恢复测试

    • 模拟节点故障,观察 Pod 重新调度到其他节点后数据是否保留。

六、常见问题

1. PVC 无法绑定
  • 检查 StorageClass 是否存在且配置正确。
  • 确认 PV 的容量和访问模式与 PVC 匹配。
2. 数据写入性能差
  • 使用 SSD 类型 StorageClass(如 AWS gp3io2 )。
  • 调整文件系统挂载参数(如 ext4discard 选项)。
3. 存储资源不足
  • 设置 ResourceQuota 限制命名空间存储使用量。
  • 启用 PVC 扩容功能(需存储驱动支持)。

总结

通过 StatefulSet + PVC + StorageClass 的组合,可为 MySQL 等有状态应用提供稳定的持久化存储,同时结合高可用、备份和监控策略,确保生产环境的可靠性和数据安全。实际部署时需根据业务需求调整存储类型、容量和访问模式。