Kubernetes Storage
Kubernetes 的存储体系由 卷(Volumes)-> 持久卷(PV)-> 持久卷声明(PVC)-> 存储类(StorageClass) 构成,是 Pod 提供持久数据能力的基础。
容器 vs Pod vs Storage
| 对象 | 生命周期 | 数据是否持久化 |
|---|---|---|
| Container | 重启会丢失 | ❌ |
| Pod | 重建会丢失 | ❌ |
| Volume(在 Pod 内) | Pod 在则在 | ❌ |
| PV(持久卷) | 与 Pod 分离 | ✅ |
| PVC(声明) | Pod 重建后仍绑定 | ✅ |
Volume 是 Pod 级别的存储,Pod 删除后 Volume 数据也通常被删除。
常见 Volume 类型
- Pod 每次重建数据丢失。
- 默认类型。
- 最适合 临时缓存、工作目录、缓冲区。
volumes:
- name: cache
emptyDir: {}
- 把主机路径挂载到容器。
- 强依赖 Node,不可调度迁移。
- 生产环境不建议使用。
把配置、环境变量注入到 Pod。
组合多个源的特殊卷(configMap/secret/DownwardAPI)。
只挂载一个子目录,而不是整个卷。
➡️ Volume 是短期存储,不适用于持久化。
PV 是集群级别资源(ClusterScope),独立于 Pod 存在。
它描述了后端存储:
- 本地磁盘
- NFS
- Ceph / CephFS / RBD
- iSCSI
- 云厂商存储(AWS EBS、Aliyun Disk、GCP PD…)
- CSI 驱动
指定关联的 StorageClass。
访问模式:
| 值 | 含义 |
|---|---|
| ReadWriteOnce (RWO) | 单节点读写(最常用) |
| ReadOnlyMany (ROX) | 多节点只读 |
| ReadWriteMany (RWX) | 多节点读写(NFS, CephFS) |
| ReadWriteOncePod (RWOP) | 仅 1 个 Pod 可挂载 |
- Retain(推荐业务需要手动处理)
- Delete
- Recycle(已废弃)
PVC 是 Pod 向集群申请存储的一种 “声明”。
它声明:
- 大小
- 访问模式
- 关联的 StorageClass
PVC 会与 PV 绑定,绑定后 Pod 就可以使用它。
StorageClass 定义:
- 存储后端(Volume plugin 或 CSI)
- 回收策略
- 动态供应(Dynamic Provisioning)
PVC 不再需要提前创建 PV。
创建 PVC -> 控制器自动创建 PV -> 自动绑定。
📌 生产环境 99% 使用 StorageClass + Dynamic Provisioning
provisioner: kubernetes.io/no-provisioner # 手动
parameters:
type: gp3 # 云厂商磁盘类型
reclaimPolicy: Delete # 自动删除
allowVolumeExpansion: true # 运行中扩容
volumeBindingMode: WaitForFirstConsumer
volumeBindingMode
| 模式 | 解释 |
|---|---|
| Immediate | 分配 PV 后立即绑定(默认) |
| WaitForFirstConsumer(推荐) | 直到 Pod 调度后才决定在哪个 node 创建存储 |
📌 强烈推荐
statefulset + local storage 必须使用 WaitForFirstConsumer,否则无法调度。
现代存储(Ceph, NFS, 云硬盘)都走 CSI。
CSI 插件能力:
- 创建卷
- 删除卷
- 挂载/卸载
- 快照
- 克隆
- 扩容
| 场景 | 推荐存储 |
|---|---|
| MySQL / PostgreSQL | LocalPV / RBD / 云盘(RWO) |
| MongoDB / Redis | LocalPV / RBD |
| Nginx 缓存 | emptyDir |
| 多 pod 共享文件 | NFS / CephFS(RWX) |
| 日志收集 | hostPath(只读) |
| 大文件分布式 | CephFS / GlusterFS |
| 需要备份恢复 | 支持快照的 CSI(Ceph RBD, AWS EBS) |
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-pvc
StatefulSet 会自动为每个 Pod 生成独立 PVC:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: local-storage
resources:
requests:
storage: 20Gi
📌 自动生成:
- data-mysql-0
- data-mysql-1
- data-mysql-2
Local PV = Pod 只能调度到同一个 Node,但性能极高。
适用于:
- 高性能数据库(MySQL, PostgreSQL, Kafka)
- 大量 IOPS 场景
必须使用:
volumeBindingMode: WaitForFirstConsumer
vm.dirty_ratio = 5
vm.dirty_background_ratio = 2
fs.inotify.max_user_watches = 1048576
使用 overlayfs2,避免 overlayfs 不一致问题。
- XFS(数据库)
- EXT4(一般应用)
- 使用 Local PV 或 RBD
- production 必用 PV/PVC,不要用 hostPath
- 使用 StatefulSet,不要 Deployment
使用 RWX(NFS / CephFS)
emptyDir(可以内存 tmpfs)
emptyDir:
medium: Memory
Local PV + SSD
- ❌ hostPath 持久化业务数据
- ❌ 使用 latest image tag 持久化数据
- ❌ Pod 使用同一个 PV(除 RWX 外)