qidao123.com技术社区-IT企服评测·应用市场

标题: K8S - Volume 与 PersistentVolume - 容器存储与数据持久化 [打印本页]

作者: 梦见你的名字    时间: 2025-5-9 08:09
标题: K8S - Volume 与 PersistentVolume - 容器存储与数据持久化
一、引言

在 Kubernetes 中,容器默认接纳临时存储(Ephemeral Storage),这意味着 Pod 一旦重启或重建,其内部数据将完全丢失。
然而,在生产情况中,许多关键应用(如数据库、日记系统、内容管理平台)都需要保证数据持久化与高可用性。为此,Kubernetes 提供了以下核心机制:
• Volume:为 Pod 提供临时或持久的存储挂载本领。
• PersistentVolume (PV):集群级别的存储资源抽象,独立于 Pod 生命周期。
• PersistentVolumeClaim (PVC):用户对存储资源的声明,可实现动态或静态绑定 PV。
二、核心原理

2.1 Volume:Pod 级别的存储机制
Volume 是 Pod 内部的存储抽象,其生命周期与 Pod 同等。常见类型如下:

范围性:
• 临时性存储无法满意数据持久化需求
• 配置复杂,缺乏资源解耦本领
2.2 PV 与 PVC:存储资源的解耦模型
Kubernetes 通过 PV/PVC 模型实现应用与底层存储的解耦:
PersistentVolume(PV)
• 静态供给:管理员预创建,指定容量、访问模式、类型等
• 动态供给:通过 StorageClass主动按需创建(如 AWS EBS)
关键字段:
• capacity: 存储容量,如 1Gi
• accessModes: 访问模式(ReadWriteOnce、ReadOnlyMany等)
• persistentVolumeReclaimPolicy: 回收计谋(Retain、Delete)
PersistentVolumeClaim(PVC)
• 用户声明对存储的需求,K8s 主动匹配合适的 PV
StorageClass
• 定义动态供给模板(云存储参数、文件系统类型等)
• 实现 PV 的按需主动化创建
模型关系图:
  1. # 静态供给流程
  2. ┌─────────────┐         绑定           ┌─────────────┐
  3. │   PV (预创建)  │ ◄──────────────────── │    PVC      │
  4. └──────┬──────┘                      └──────┬──────┘
  5.        │                                    │
  6.        │              挂载                  │
  7.        ▼                                    ▼
  8. ┌───────────────────────────────────────────────────┐
  9. │                        Pod                        │
  10. │          (通过 volumes 字段引用 PVC)                │
  11. └───────────────────────────────────────────────────┘
复制代码
  1. # 动态供给流程
  2. ┌─────────────┐         动态创建         ┌─────────────┐
  3. │ StorageClass │ ───────────────────────►│     PV      │
  4. └───────┬──────┘                         └──────┬──────┘
  5.         │          自动触发                       │
  6.         ▼                                        ▼
  7. ┌─────────────┐         绑定           ┌─────────────┐
  8. │    PVC      │ ◄────────────────────── │    Pod     │
  9. └─────────────┘         挂载            └─────────────┘
复制代码
2.3 核心参数详解
Access Modes(访问模式)
• ReadWriteOnce (RWO):单节点读写(如云硬盘)
• ReadOnlyMany (ROX):多节点只读
• ReadWriteMany (RWX):多节点读写(需 NFS 或分布式存储支持)
Reclaim Policy(回收计谋)
• Retain:PVC 删除后保留数据(需手动清理)
• Delete:PVC 删除后主动烧毁数据(云平台默认)
• Recycle(已废弃):清空数据再重用(不保举)
三、实战演示:MySQL 数据持久化

3.1 情况准备(以 Minikube 为例)
  1. # 安装工具
  2. brew install kubectl minikube
  3. # 启动集群
  4. minikube start --driver=docker
复制代码
3.2 创建 PersistentVolume(静态供给)
步调 1:定义 PV(测试用 hostPath)
  1. mysql-pv.yaml:
  2. apiVersion: v1
  3. kind: PersistentVolume                  # 资源类型
  4. metadata:
  5.   name: mysql-pv                        # PV名称,集群内唯一标识
  6. spec:
  7.   capacity:
  8.     storage: 1Gi                        # 存储容量(GiB单位)
  9.   accessModes:
  10.     - ReadWriteOnce                     # 访问模式:单节点读写挂载
  11.   persistentVolumeReclaimPolicy: Retain # 回收策略:删除PVC后保留数据(需手动清理)
  12.   hostPath:
  13.     path: /data/mysql                   # 节点本地存储路径(仅适合单节点测试环境)
复制代码
注:ReadWriteOnce 表示同时只能被一个 Pod 挂载
步调 2:摆设并查看状态
  1. kubectl apply -f mysql-pv.yaml
  2. kubectl get pv   # 状态应为 Available
  3. 输出:
  4. NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
  5. mysql-pv   1Gi        RWO            Retain           Available                                   5s
  6. # 注意 STATUS 应为 Available
复制代码
3.3 创建 PersistentVolumeClaim
步调 1:定义 PVC
  1. mysql-pvc.yaml:
  2. apiVersion: v1
  3. kind: PersistentVolumeClaim
  4. metadata:
  5.   name: mysql-pvc
  6. spec:
  7.   accessModes:
  8.     - ReadWriteOnce
  9.   resources:
  10.     requests:
  11.       storage: 1Gi
复制代码
步调 2:摆设并绑定 PV
  1. kubectl apply -f mysql-pvc.yaml
  2. kubectl get pvc   # 应为 Bound
  3. kubectl get pv    # 状态变为 Bound
  4. 输出:
  5. # 部署 PVC 后查看绑定状态
  6. $ kubectl get pvc
  7. NAME        STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
  8. mysql-pvc   Bound    mysql-pv   1Gi        RWO                           10s
  9. $ kubectl get pv  # PV 状态变化
  10. NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               AGE
  11. mysql-pv   1Gi        RWO            Retain           Bound    default/mysql-pvc   2m
复制代码
3.4 摆设 MySQL 并挂载 PVC
步调 1:定义 Deployment
  1. mysql-deployment.yaml:
  2. apiVersion: apps/v1
  3. kind: Deployment                       
  4. metadata:
  5.   name: mysql                        
  6. spec:
  7.   selector:
  8.     matchLabels:
  9.       app: mysql                     
  10.   template:
  11.     metadata:
  12.       labels:
  13.         app: mysql                  
  14.     spec:
  15.       containers:
  16.         - name: mysql
  17.           image: mysql:8.0            # 使用官方MySQL 8.0镜像
  18.           env:
  19.             - name: MYSQL_ROOT_PASSWORD
  20.               value: "password"        # 明文密码(生产环境应用Secret替代)
  21.           ports:
  22.             - containerPort: 3306      # 暴露MySQL默认端口
  23.           volumeMounts:
  24.             - name: mysql-storage
  25.               mountPath: /var/lib/mysql # 挂载数据库存储路径(数据持久化)
  26.       volumes:
  27.         - name: mysql-storage
  28.           persistentVolumeClaim:
  29.             claimName: mysql-pvc        # 绑定预先创建的PVC(需确保存在)
复制代码
步调 2:摆设并查看 Pod
  1. kubectl apply -f mysql-deployment.yaml
  2. kubectl get pods -l app=mysql
  3. 输出:
  4. # 查看 Pod 启动过程(展示完整生命周期)
  5. $ kubectl get pods -l app=mysql --watch
  6. NAME                    READY   STATUS              RESTARTS   AGE
  7. mysql-8c6b66d88-7w2vs   0/1     ContainerCreating   0          10s
  8. mysql-8c6b66d88-7w2vs   1/1     Running             0          25s  # 最终状态
复制代码
3.5 数据持久化验证
步调 1:写入测试数据
  1. kubectl exec -it $(kubectl get pod -l app=mysql -o jsonpath="{.items[0].metadata.name}") -- \
  2.   mysql -uroot -ppassword -e "CREATE DATABASE test;"
复制代码
步调 2:模拟 Pod 故障并验证数据
  1. kubectl delete pod -l app=mysql
  2. kubectl get pods -l app=mysql   # 等待新 Pod 启动
  3. # 验证是否存在 test 数据库
  4. kubectl exec -it $(kubectl get pod -l app=mysql -o jsonpath="{.items[0].metadata.name}") -- \
  5.   mysql -uroot -ppassword -e "SHOW DATABASES;"
  6. 预期结果:应包含 test数据库,验证数据持久化成功。
  7. # 写入测试数据后检查(显示完整输出)
  8. $ kubectl exec -it mysql-8c6b66d88-7w2vs -- mysql -uroot -ppassword -e "SHOW DATABASES;"
  9. +--------------------+
  10. | Database           |
  11. +--------------------+
  12. | information_schema |
  13. | mysql              |
  14. | performance_schema |
  15. | sys                |
  16. | test               |  # 新增的测试数据库
  17. +--------------------+
  18. # 删除 Pod 后观察新实例
  19. $ kubectl delete pod mysql-8c6b66d88-7w2vs
  20. pod "mysql-8c6b66d88-7w2vs" deleted
  21. $ kubectl get pods -l app=mysql
  22. NAME                    READY   STATUS    RESTARTS   AGE
  23. mysql-8c6b66d88-kk9xp   1/1     Running   0          45s  # 新 Pod
  24. # 二次验证数据
  25. $ kubectl exec -it $(kubectl get pod -l app=mysql -o name) -- mysql -uroot -ppassword -e "SHOW DATABASES;"
  26. # 若出现错误"Error from server (NotFound): pods not found",说明 Pod 尚未完全启动
复制代码
四、生产情况最佳实践


StorageClass 示例(AWS EBS)
  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4.   name: ebs-gp3
  5. provisioner: kubernetes.io/aws-ebs
  6. parameters:
  7.   type: gp3                      # 通用型 SSD
  8.   fsType: ext4                   # 文件系统类型
  9.   iops: "3000"                   # 性能配置(可选)
  10.   encrypted: "true"              # 启用加密
复制代码
生产情况必须项:

五、总结

5.1 核心重点
• Volume:实用于 Pod 内部共享临时数据,但无法跨生命周期持久化。
• PV/PVC 模型:解耦存储供应与消费,支持动态供给与多类型后端存储。
• 核心选型发起:
• 根据业务需要选择 accessModes与 reclaimPolicy
• 生产情况优先使用动态供给 + 云存储方案
5.2 常见问题排查表


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




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4