
Kubernetes 中计算是短暂的,数据是永久的。Pod 可以被调度、重建和迁移,但业务数据一旦丢失,往往无法恢复。因此,Kubernetes 设计了一套解耦、分层且可扩展的存储模型,其核心思想是:Pod 不直接使用存储,而是通过 PersistentVolumeClaim (PVC) 间接声明需求。这套机制功能强大,但也因其复杂性,成为新手最难理解、生产事故最多、配置最易出错的模块之一。本文将系统性地介绍 Kubernetes 持久化存储的核心组件:Volume、PersistentVolume (PV)、PersistentVolumeClaim (PVC) 和 StorageClass,并通过原理、配置、示例代码及生产实践,帮助全面掌握。
在深入细节前,需建立全局认知。Kubernetes 存储模型是一个分层结构:
1、应用层 (Pod):通过 volumeMounts 声明容器内的挂载点。
2、K8s 资源层:
3、底层存储系统:通过 CSI Driver 等插件对接 AWS EBS、NFS、Ceph 等具体存储后端。
核心设计思想是解耦:应用只关心 PVC(声明“我要什么”),而不需要关心底层 PV 的具体实现(“如何提供”)。
Volume 是 Pod 中容器可访问的存储目录。其生命周期通常与 Pod 绑定。以下是一个 Pod 使用多种 Volume 的示例:
apiVersion: v1
kind: Pod
metadata:
name: volume-demo
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: html-volume # 挂载名为 html-volume 的卷
mountPath: /usr/share/nginx/html
- name: config-volume # 挂载名为 config-volume 的卷
mountPath: /etc/nginx/conf.d
volumes:
- name: html-volume
emptyDir: {} # 使用 emptyDir 类型卷,Pod 删除则数据丢失
- name: config-volume
configMap: # 使用 ConfigMap 类型卷,注入配置
name: nginx-config常见 Volume 类型与定位:
类型 | 生命周期 | 典型用途 |
|---|---|---|
emptyDir | Pod 级 | 临时数据、缓存 |
hostPath | 节点级 | 本地调试(生产慎用) |
configMap / secret | 集群级 | 配置、证书 |
persistentVolumeClaim | 跨 Pod | 生产持久化数据 |
对于需要持久化的生产数据,必须使用基于 PV/PVC 的 Volume。
PV 是集群中的一块存储资源,由管理员预先制备,或由 StorageClass 动态创建。它是一个独立的集群资源对象。
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-demo
labels:
environment: production
spec:
capacity:
storage: 100Gi # 存储容量
volumeMode: Filesystem # 卷模式:文件系统(Filesystem)或块设备(Block)
accessModes: # 访问模式
- ReadWriteMany # 支持多节点读写
persistentVolumeReclaimPolicy: Retain # 回收策略:保留
storageClassName: nfs-storage # 所属存储类名称
nfs: # 存储后端类型为 NFS
server: 192.168.1.100
path: /data/nfs-sharePV 核心参数:
参数 | 说明 |
|---|---|
capacity | 存储容量 |
accessModes | 访问模式 ( ReadWriteOnce , ReadWriteMany , ReadOnlyMany ) |
volumeMode | Filesystem (文件系统) 或 Block (块设备) |
persistentVolumeReclaimPolicy | 回收策略 ( Retain , Delete , Recycle ) |
storageClassName | 关联的 StorageClass 名称 |
PVC 是用户对存储的请求。它不直接代表存储,而是一份“需求说明书”。Kubernetes 控制器会根据 PVC 的请求,去绑定一个符合条件的 PV,或者根据指定的 StorageClass 动态创建一个 PV 来满足它。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
spec:
accessModes:
- ReadWriteOnce # 请求单节点读写模式
storageClassName: fast # 指定所需的存储类
resources:
requests:
storage: 50Gi # 请求 50GiB 存储空间PVC 的本质:Pod 引用 PVC,PVC 绑定 PV。应用开发者只需编写 PVC,无需关心底层存储细节。
StorageClass 定义了创建 PV 的“模板”和“策略”,实现了存储的动态供应(Dynamic Provisioning)。它是解耦应用与底层存储实现的关键。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/gce-pd # 制备器,决定使用哪种后端存储
parameters:
type: pd-ssd # 传递给制备器的参数,此处指定为SSD类型云盘
allowVolumeExpansion: true # 允许卷扩容
volumeBindingMode: WaitForFirstConsumer # 卷绑定模式:延迟绑定StorageClass 至关重要
1、解耦:应用通过 PVC 请求“fast”存储,而“fast”在 AWS 可能是 gp3,在 GCP 可能是 pd-ssd。
2、策略统一:集中定义性能、加密、备份、扩容等策略。
3、动态供应:无需管理员手动创建 PV,按需自动创建,提升效率。
模式 | 缩写 | 含义 | 常见场景 |
|---|---|---|---|
ReadWriteOnce | RWO | 卷可被单个节点以读写模式挂载 | 数据库 (MySQL, PostgreSQL)、消息队列 (Kafka) |
ReadWriteMany | RWX | 卷可被多个节点以读写模式挂载 | 共享文件系统 (NFS, CephFS) |
ReadOnlyMany | ROX | 卷可被多个节点以只读模式挂载 | 只读配置分发 |
存储是否支持 RWX 取决于底层存储系统(如 NFS 支持,AWS EBS 不支持),而非 Kubernetes 本身。
策略 | 行为 | 生产建议 |
|---|---|---|
Retain | 删除 PVC 后,PV 及其数据保留。需手动清理。 | 核心生产数据推荐,防止误删。 |
Delete | 删除 PVC 后,自动删除对应的 PV 和底层存储卷。 | 云环境临时数据,简化管理。 |
Recycle | (已废弃) 删除数据但保留卷。 | 不推荐使用。 |
StatefulSet 为有状态应用设计,其与存储的配合有特殊规则。
# StatefulSet 片段示例
spec:
volumeClaimTemplates: # PVC 模板,不是直接引用 PVC
- metadata:
name: data # 每个 Pod 都会根据此模板生成独立的 PVC
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast-ssd
resources:
requests:
storage: 200Gi规则:
1、应用无感知:应用通过声明式的 PVC 请求存储,无需关心底层是 NFS、Ceph 还是云盘。
2、平台统一管理:通过 StorageClass,平台管理员可以统一定义和提供不同等级(如快、慢、加密)的存储服务。
3、数据生命周期独立:数据的生命周期(创建、保留、删除)通过 PV 的 reclaimPolicy 管理,独立于使用它的 Pod 或 Deployment/StatefulSet。
Kubernetes 的持久化存储模型,其核心价值并非简单地“提供存储空间”,而是帮助开发者安全、可控、可恢复地管理应用的数据生命周期,这是构建可靠云原生应用的关键基石。
“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!