☰
Kubernetes中使用Ceph RBD部署高可用MySQL
2026/11/6 7:13:02 网站建设 项目流程

1. 项目概述

在云原生环境中,数据库的高可用性和持久化存储一直是关键挑战。本文将详细介绍如何在Kubernetes集群中使用Ceph RBD作为后端存储部署MySQL数据库。这种架构结合了Kubernetes的编排能力和Ceph的分布式存储优势,为MySQL提供了企业级的存储解决方案。

我最近在一个生产环境中成功实施了这种方案,使用的是OpenEuler 22.04操作系统、Ceph 16.2.7(Pacific版本)和Kubernetes 1.32.2。这种组合特别适合需要高可用性和数据持久化的场景,比如电商平台的订单数据库或金融系统的交易记录存储。

2. 环境准备与架构设计

2.1 基础环境要求

在开始之前,我们需要确保以下组件已经就绪:

  • 运行OpenEuler 22.04的服务器节点(至少3个节点用于生产环境)
  • 正常运行的Ceph集群(版本16.2.7或更高)
  • Kubernetes集群(版本1.32.2)
  • 网络互通:Kubernetes节点能够访问Ceph Monitor的6789端口

提示:生产环境中建议Ceph和Kubernetes使用独立的网络,但确保网络策略允许必要的通信。

2.2 架构设计解析

整个方案的架构分为三个主要部分:

  1. Ceph存储层:提供分布式块存储服务,通过RBD(RADOS Block Device)方式为MySQL提供持久化卷
  2. Kubernetes CSI驱动层:作为中间桥梁,使Kubernetes能够动态配置和管理Ceph RBD卷
  3. MySQL应用层:运行在Kubernetes中的MySQL实例,数据存储在Ceph RBD卷上

这种设计的优势在于:

  • 数据高可用:Ceph的副本机制确保数据安全
  • 弹性扩展:可根据需求动态调整存储容量
  • 性能可控:可以针对MySQL的I/O特性优化Ceph池的参数

3. Ceph CSI驱动部署

3.1 CSI驱动安装与配置

首先需要在Kubernetes集群中部署Ceph CSI驱动,这是连接Kubernetes和Ceph的关键组件。

wget https://github.com/ceph/ceph-csi/archive/refs/tags/v3.15.0.zip tar xf ceph-csi-3.15.0.tar.gz -C /usr/local/ cd /usr/local/ceph-csi-3.15.0/deploy/rbd/kubernetes

3.2 关键配置文件修改

3.2.1 csi-config-map.yaml

这个配置文件定义了Ceph集群的基本信息:

apiVersion: v1 kind: ConfigMap metadata: name: "ceph-csi-config" data: config.json: |- [ { "clusterID": "65eac714-0bd5-11f1-9e23-000c298c1628", "monitors": [ "192.168.198.22:6789", "192.168.198.41:6789", "192.168.198.43:6789" ] } ]

注意:clusterID可以通过在Ceph集群上执行ceph -s命令获取,Monitors地址应填写Ceph集群中所有Monitor节点的地址。

3.2.2 csi-rbdplugin-provisioner.yaml

这个文件定义了CSI的Provisioner组件,负责动态创建存储卷:

apiVersion: apps/v1 kind: Deployment metadata: name: csi-rbdplugin-provisioner namespace: default spec: replicas: 3 selector: matchLabels: app: csi-rbdplugin-provisioner template: metadata: labels: app: csi-rbdplugin-provisioner spec: containers: - name: csi-rbdplugin image: quay.io/cephcsi/cephcsi:v3.14.0 args: - "--nodeid=$(NODE_ID)" - "--type=rbd" - "--controllerserver=true" - "--v=5" - "--drivername=rbd.csi.ceph.com" env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: NODE_ID valueFrom: fieldRef: fieldPath: spec.nodeName

3.3 部署CSI驱动

完成配置文件修改后,可以部署CSI驱动:

kubectl apply -f csi-config-map.yaml kubectl apply -f csi-provisioner-rbac.yaml kubectl apply -f csi-nodeplugin-rbac.yaml kubectl apply -f csi-rbdplugin-provisioner.yaml kubectl apply -f csi-rbdplugin.yaml

部署完成后,检查Pod状态:

kubectl get pods -n default | grep csi-rbd

应该看到类似以下的输出,所有Pod都应处于Running状态:

csi-rbdplugin-provisioner-xxx 6/6 Running 0 2m csi-rbdplugin-xxx 3/3 Running 0 2m

4. Ceph存储准备

4.1 创建专用存储池

在Ceph集群上为MySQL创建专用的存储池:

ceph osd pool create k8s_mysql_pool 128 128

专业建议:根据预计的数据量和性能需求调整PG(Placement Group)数量。对于生产环境,可以使用Ceph官方提供的PG计算器确定合适的值。

4.2 创建访问用户

为Kubernetes创建专用的Ceph用户:

ceph auth get-or-create client.k8s_mysql_pool_user mon 'allow r' osd 'allow rw pool=k8s_mysql_pool' -o ceph.client.k8s_mysql_pool_user.keyring

获取用户的key并转换为base64格式,后续Kubernetes会用到:

echo -n "k8s_mysql_pool_user" | base64 echo -n "AQDveaJpjt5DIRAA3FhB6UBN9jzRs72gKwN3Qw==" | base64

5. Kubernetes存储配置

5.1 创建Ceph Secret

在Kubernetes中创建Secret来存储Ceph凭据:

apiVersion: v1 kind: Secret metadata: name: ceph-secret namespace: default type: "kubernetes.io/rbd" data: userID: azhzX215c3FsX3Bvb2xfdXNlcg== userKey: QVFEdmVhSnBqdDVEQVJBQTNGaEI2VUJOOWp6UnM3MmdLd04zUXc9PQ==

应用这个配置:

kubectl apply -f ceph-secret.yaml

5.2 创建StorageClass

定义动态存储供应:

apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-rbd provisioner: rbd.csi.ceph.com parameters: clusterID: 65eac714-0bd5-11f1-9e23-000c298c1628 pool: k8s_mysql_pool monitors: 192.168.198.22:6789,192.168.198.41:6789,192.168.198.43:6789 csi.storage.k8s.io/provisioner-secret-name: ceph-secret csi.storage.k8s.io/provisioner-secret-namespace: default csi.storage.k8s.io/controller-expand-secret-name: ceph-secret csi.storage.k8s.io/controller-expand-secret-namespace: default csi.storage.k8s.io/node-stage-secret-name: ceph-secret csi.storage.k8s.io/node-stage-secret-namespace: default fsType: ext4 imageFormat: "2" imageFeatures: layering reclaimPolicy: Retain volumeBindingMode: Immediate

重要参数说明:

  • reclaimPolicy: Retain确保删除PVC时不会删除底层Ceph RBD镜像
  • volumeBindingMode: Immediate表示在创建PVC时立即绑定PV

6. MySQL部署与配置

6.1 创建MySQL Secret

安全存储MySQL的root密码:

apiVersion: v1 kind: Secret metadata: name: mysql-password type: Opaque data: username: cm9vdA== password: QWRtaW4xMjM0 mysql-root-password: QWRtaW4xMjM0 mysql-password: QWRtaW4xMjM0 mysql-database: bXlkYg==

6.2 部署MySQL StatefulSet

使用StatefulSet部署MySQL,确保稳定的网络标识和持久化存储:

apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: serviceName: mysql replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0.45 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-password key: mysql-root-password ports: - containerPort: 3306 volumeMounts: - name: data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: ceph-rbd resources: requests: storage: 1Gi

6.3 创建MySQL Service

暴露MySQL服务:

apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 selector: app: mysql clusterIP: None

7. 验证与测试

7.1 检查Pod状态

kubectl get pods -l app=mysql

应该看到类似输出:

NAME READY STATUS RESTARTS AGE mysql-0 1/1 Running 0 2m

7.2 验证数据持久化

  1. 连接到MySQL并创建测试数据:
kubectl exec -it mysql-0 -- mysql -uroot -pAdmin1234 -e "CREATE DATABASE testdb; USE testdb; CREATE TABLE test (id INT); INSERT INTO test VALUES (1);"
  1. 删除Pod并验证数据:
kubectl delete pod mysql-0 # 等待Pod重新创建 kubectl exec -it mysql-0 -- mysql -uroot -pAdmin1234 -e "USE testdb; SELECT * FROM test;"

应该能看到之前插入的数据(值为1的记录)。

7.3 检查Ceph RBD状态

在Ceph集群上检查RBD镜像:

rbd -p k8s_mysql_pool ls

应该看到类似如下的输出,表明Kubernetes已经成功创建了RBD镜像:

csi-vol-xxxxxx

8. 性能优化与生产建议

8.1 Ceph池优化

对于生产环境的MySQL,建议对Ceph池进行以下优化:

ceph osd pool set k8s_mysql_pool size 3 ceph osd pool set k8s_mysql_pool min_size 2 ceph osd pool set k8s_mysql_pool crush_rule replicated_ssd

这些命令将:

  • 设置数据副本数为3
  • 设置最小可用副本为2
  • 使用SSD优化的CRUSH规则(如果集群有SSD)

8.2 Kubernetes资源限制

为MySQL容器设置适当的资源限制:

resources: requests: memory: "2Gi" cpu: "1" limits: memory: "4Gi" cpu: "2"

8.3 MySQL参数调优

在MySQL配置中增加以下参数优化Ceph存储性能:

- name: MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT value: "2" - name: MYSQL_INNODB_FLUSH_METHOD value: "O_DIRECT" - name: MYSQL_INNODB_IO_CAPACITY value: "2000"

9. 故障排查与常见问题

9.1 PVC处于Pending状态

可能原因和解决方案:

  1. CSI驱动未正确安装:检查CSI Pod是否全部运行正常
  2. Ceph认证失败:验证Secret中的userID和userKey是否正确
  3. 网络连接问题:确保Kubernetes节点可以访问Ceph Monitor端口

9.2 MySQL无法启动

检查点:

  1. 查看Pod日志:kubectl logs mysql-0
  2. 验证存储是否挂载:kubectl exec -it mysql-0 -- df -h
  3. 检查PVC状态:kubectl get pvc

9.3 性能问题

如果遇到性能问题:

  1. 检查Ceph集群健康状况:ceph status
  2. 监控IO延迟:ceph osd perf
  3. 考虑使用Ceph的缓存层或为MySQL池分配更多OSD

10. 扩展与高可用方案

10.1 MySQL主从复制

可以通过部署多个MySQL实例并配置复制来实现高可用:

replicas: 3

然后在MySQL配置中添加复制相关参数。

10.2 使用CephFS替代RBD

对于需要多Pod共享存储的场景,可以考虑使用CephFS:

provisioner: cephfs.csi.ceph.com

10.3 监控与告警

建议部署以下监控组件:

  • Prometheus监控Ceph集群
  • MySQL Exporter监控数据库指标
  • Grafana展示监控数据

11. 备份与恢复策略

11.1 Ceph RBD快照

利用Ceph的快照功能备份数据:

rbd snap create k8s_mysql_pool/csi-vol-xxxxxx@backup-20240501

11.2 Kubernetes VolumeSnapshot

使用Kubernetes的VolumeSnapshot API:

apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: mysql-snapshot spec: volumeSnapshotClassName: csi-rbdplugin-snapclass source: persistentVolumeClaimName: mysql-pvc

11.3 MySQL逻辑备份

定期执行mysqldump并存储到安全位置:

kubectl exec -it mysql-0 -- mysqldump -uroot -pAdmin1234 --all-databases > backup.sql

12. 安全加固建议

12.1 Ceph安全

  1. 限制网络访问:配置Ceph防火墙只允许Kubernetes节点访问
  2. 启用Ceph认证:确保所有访问都经过认证
  3. 定期轮换密钥:定期更新Ceph用户密钥

12.2 Kubernetes安全

  1. 使用NetworkPolicy限制MySQL Pod的网络访问
  2. 为MySQL Service配置TLS加密
  3. 使用PodSecurityPolicy限制容器的权限

12.3 MySQL安全

  1. 避免使用root账户进行应用连接
  2. 定期更改数据库密码
  3. 启用审计日志监控数据库访问

13. 成本优化

13.1 存储分层

对于历史数据,可以配置Ceph的冷热数据分层:

  • 热数据存储在SSD池
  • 冷数据迁移到HDD池

13.2 压缩与去重

启用Ceph的压缩和去重功能:

ceph osd pool set k8s_mysql_pool compression_mode aggressive

13.3 容量规划

定期评估存储使用情况,避免过度配置:

  • 设置PVC自动扩展策略
  • 监控存储使用趋势
  • 清理不必要的数据

14. 实际应用案例

14.1 电商平台订单系统

在某电商平台中,我们使用这种架构处理日均10万+订单:

  • 3节点Kubernetes集群
  • 5节点Ceph集群(混合SSD+HDD)
  • 每天自动快照备份
  • 读写分离配置

14.2 物联网数据存储

为某物联网项目存储设备数据:

  • 高写入负载优化
  • 使用Ceph的EC(纠删码)池降低成本
  • 配置自动扩展策略

15. 未来演进方向

  1. 多集群部署:跨多个Kubernetes集群共享Ceph存储
  2. 性能优化:结合SPDK进一步提升I/O性能
  3. 自动化运维:实现自动扩缩容和故障自愈
  4. 云原生集成:与Operators框架深度集成,实现一键部署

16. 经验总结与建议

在实际部署过程中,我总结了以下几点关键经验:

  1. 版本兼容性至关重要:确保Kubernetes、Ceph和CSI驱动的版本兼容。我们曾因版本不匹配导致性能问题。

  2. 监控先行:在部署生产负载前,先建立完善的监控体系。Ceph的ceph-mgr模块和Prometheus exporter是很好的起点。

  3. 性能基准测试:使用fio等工具对Ceph RBD进行基准测试,了解实际性能表现。我们发现在默认配置下,随机写性能可能不如预期。

  4. 资源隔离:为MySQL的Ceph池单独配置CRUSH规则,避免与其他工作负载争抢资源。

  5. 备份策略:除了Ceph快照,我们还实现了逻辑备份和异地备份的多重保护。

  6. 渐进式部署:先在测试环境验证所有功能,然后逐步迁移生产负载。我们分三个阶段完成了迁移,每个阶段都进行了充分验证。

  7. 文档记录:详细记录所有配置和操作步骤。当半年后需要扩容时,完整的文档节省了大量时间。

对于考虑类似架构的团队,我的建议是:

  • 从小规模开始,验证核心功能
  • 投入时间理解Ceph和Kubernetes存储子系统的工作原理
  • 建立自动化运维流程,减少人工干预
  • 定期演练灾难恢复流程

这种架构虽然初期投入较大,但为我们的关键业务数据库提供了企业级的可靠性和灵活性,长期来看非常值得。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询