容器默认的文件系统是临时的,Pod 删除后数据丢失。Kubernetes 通过 Volume 抽象提供持久化存储。本文介绍几种常用卷类型:emptyDir(临时存储)、hostPath(节点存储)、PersistentVolumeClaim(持久卷声明)以及 CSI(容器存储接口)。掌握这些,你可以为应用提供从临时缓存到企业级持久化存储的完整方案。
一、Volume 基础
Volume 在 Pod 级别定义,挂载到容器内的指定路径。不同类型的卷支持不同的后端(本地磁盘、NFS、云存储等)。
二、emptyDir:临时存储
emptyDir 在 Pod 调度到节点时创建,初始为空,Pod 删除时数据永久丢失。适用于同一 Pod 内多个容器共享临时数据、缓存或检查点。
YAML 示例:
apiVersion:v1kind:Podmetadata:name:emptydir-demospec:containers:-name:writerimage:busyboxcommand:["/bin/sh","-c","echo hello > /data/hello.txt && sleep 3600"]volumeMounts:-name:shared-datamountPath:/data-name:readerimage:busyboxcommand:["/bin/sh","-c","cat /data/hello.txt && sleep 3600"]volumeMounts:-name:shared-datamountPath:/datavolumes:-name:shared-dataemptyDir:{}emptyDir 可以指定存储介质(默认磁盘,可改为内存):
emptyDir:medium:MemorysizeLimit:128Mi# 可选,限制内存使用量三、hostPath:节点存储
hostPath 将节点文件系统的路径挂载到 Pod。常用于:
访问节点上的 Docker socket(/var/run/docker.sock)
日志或监控 agent 读取 /var/log
节点级配置文件(如 kubelet 配置)
注意事项:
不同节点上的文件内容可能不同,导致 Pod 行为不一致。
多 Pod 同时写 hostPath 可能冲突。
生产环境慎用,推荐使用 PersistentVolume。
YAML 示例:
apiVersion:v1kind:Podmetadata:name:hostpath-demospec:containers:-name:appimage:nginxvolumeMounts:-name:host-logsmountPath:/host/var/logvolumes:-name:host-logshostPath:path:/var/logtype:Directory# 可选:DirectoryOrCreate, File, FileOrCreate 等四、PersistentVolume(PV)与 PersistentVolumeClaim(PVC)
这是 Kubernetes 推荐的持久化存储方式。PV 是集群管理员提供的存储资源,PVC 是用户对存储的请求。PVC 绑定到 PV 后,Pod 通过 PVC 使用存储。
4.1 创建 PV(NFS 示例)
apiVersion:v1kind:PersistentVolumemetadata:name:nfs-pvspec:capacity:storage:10GiaccessModes:-ReadWriteOncepersistentVolumeReclaimPolicy:Retainnfs:server:192.168.1.100path:/exports/dataaccessModes:ReadWriteOnce(单节点读写)、ReadOnlyMany(多节点只读)、ReadWriteMany(多节点读写)。
persistentVolumeReclaimPolicy:Retain(手动清理)、Delete(自动删除)、Recycle(已废弃)。
4.2 创建 PVC
kind:PersistentVolumeClaimapiVersion:v1metadata:name:my-pvcspec:accessModes:-ReadWriteOnceresources:requests:storage:5GiKubernetes 会寻找满足请求的 PV(容量 >= 5Gi,匹配 accessMode),并绑定。如果无匹配,PVC 将保持 Pending。
4.3 在 Pod 中使用 PVC
apiVersion:v1kind:Podmetadata:name:pvc-demospec:containers:-name:appimage:nginxvolumeMounts:-name:datamountPath:/usr/share/nginx/htmlvolumes:-name:datapersistentVolumeClaim:claimName:my-pvc4.4 StorageClass 动态供给
StorageClass 允许按需自动创建 PV。管理员定义 StorageClass(如云厂商的 SSD 类型),用户 PVC 指定 storageClassName,系统会自动创建 PV。
apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:fastprovisioner:kubernetes.io/aws-ebsparameters:type:gp2---kind:PersistentVolumeClaimapiVersion:v1metadata:name:dynamic-pvcspec:accessModes:-ReadWriteOncestorageClassName:fastresources:requests:storage:10Gi五、CSI(容器存储接口)
CSI 是 Kubernetes 1.13+ 引入的标准存储接口,允许第三方存储提供商(如 AWS EBS、GCE PD、Ceph、Portworx)通过标准驱动集成到 K8s。用户无需修改 K8s 核心代码即可使用各种存储。
使用步骤:
在集群中部署 CSI 驱动(通常提供 DaemonSet + Controller 的 YAML)。
创建 StorageClass 引用 CSI 驱动。
创建 PVC 使用该 StorageClass,Pod 即可使用。
CSI 的优势:支持快照、克隆、卷扩展等高级功能。
六、存储卷的适用场景总结
七、常见问题与解决
八、最佳实践
临时数据用 emptyDir,并设置 sizeLimit 防止磁盘爆满。
生产持久化存储使用 PVC + StorageClass,避免直接使用 hostPath。
为有状态应用(如数据库)选择 ReadWriteOnce 的块存储,而非 NFS(性能问题)。
定期备份 PV 数据,PV 本身不提供备份能力。
使用 PVC 时,注意 Pod 调度与卷可用区的亲和性(云存储通常绑定节点可用区)。
九、小结
Kubernetes 提供了丰富的存储卷类型,从临时 emptyDir 到企业级 CSI。理解 PV/PVC 模型能帮助你更好地管理应用数据生命周期。合理选择存储方案,是保证状态应用稳定运行的关键。