容器天然是临时的,但应用经常需要文件、缓存、配置挂载,或者真正持久化的数据。Volume 的作用,就是把容器级运行环境变成更接近真实业务需求的运行环境。
为什么 Volume 这么重要
- 容器会重启,但数据未必能丢
- 一个 Pod 里的多个容器可能要共享文件
- 配置和密钥通常更适合挂成文件
- 存储选型会直接影响性能、可靠性和恢复策略
最值得先理解的几类 Volume
emptyDir:跟随 Pod 生命周期的临时存储configMap/secret:挂载配置和密钥persistentVolumeClaim:向集群申请持久卷hostPath:直接挂宿主机目录,少数场景有用,但非常容易被用错
emptyDir:临时,但很实用
emptyDir 很适合:
- 缓存
- 临时工作目录
- sidecar 之间共享文件
- 中间处理产物
volumes:
- name: cache
emptyDir: {}
volumeMounts:
- name: cache
mountPath: /cache
它会随着 Pod 消失而一起消失。所以它要么刚好是你需要的,要么正好是你不能用的。
配置和 Secret 挂载
Volume 也是很多工作负载接收配置的主要方式:
volumes:
- name: app-config
configMap:
name: app-config
- name: app-secret
secret:
secretName: app-secret
volumeMounts:
- name: app-config
mountPath: /etc/app/config
readOnly: true
- name: app-secret
mountPath: /etc/app/secret
readOnly: true
这部分和 kubernetes-quickstart-configmap-secret.md 是天然连着看的,那篇会更深入讲配置与密钥生命周期。
基于 PVC 的持久存储
当数据必须在 Pod 被替换后还保留下来时,通常就要进入 PVC 这条链路:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
然后在 Pod 中挂载:
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
volumeMounts:
- name: data
mountPath: /var/lib/app
这条链路更完整的解释在:
kubernetes-quickstart-pv-pvc.mdkubernetes-quickstart-storageclass.md
第一个该先做的选择:临时还是持久
在选 Volume 之前,先回答一个问题:
- 如果 Pod 没了,这份数据能不能一起没?
如果能,那 emptyDir 很可能就够。
如果不能,那就要进入 PVC、StorageClass、回收策略、备份与恢复这些更完整的存储话题。
只要先把这一步分清,很多选型问题会简单很多。
一个 Pod 内共享数据的典型模式
如果多个容器需要共享同一份文件,可以挂同一个卷:
apiVersion: v1
kind: Pod
metadata:
name: producer-consumer
spec:
volumes:
- name: shared
emptyDir: {}
containers:
- name: producer
image: busybox
command: ["sh", "-c", "while true; do date >> /data/out.txt; sleep 5; done"]
volumeMounts:
- name: shared
mountPath: /data
- name: consumer
image: busybox
command: ["sh", "-c", "tail -f /data/out.txt"]
volumeMounts:
- name: shared
mountPath: /data
这在 sidecar、日志处理和内容生成场景里都很常见。
hostPath:能用,但很容易用出问题
hostPath 是直接把宿主机目录挂进 Pod。
少数场景下它很方便,但也有明显代价:
- 可移植性差
- 把工作负载和节点强绑定
- 容易带来宿主机级安全风险
如果你并不强控制节点生命周期,hostPath 通常不该是第一选择。
Volume 和有状态工作负载的关系
很多有状态系统需要的不只是“有卷”,还需要:
- 稳定身份
- 稳定 DNS
- 可预测的更新顺序
所以存储这条线,通常会自然连到:
kubernetes-quickstart-pv-pvc.mdkubernetes-quickstart-storageclass.mdkubernetes-quickstart-statefulset.md
常见故障模式
Pod 一直 Pending
很多时候是 PVC 绑定或 StorageClass 相关问题。
挂载失败
这时候可能已经进入 CSI、节点权限或后端存储本身的问题域了。
重启后数据不见了
常见原因是本该持久化的数据被放进了临时卷。
权限不对
通常是文件系统属主、securityContext 或挂载路径本身不匹配。
常用排障命令
kubectl describe pod <pod-name>
kubectl describe pvc <pvc-name>
kubectl get pv
更深层的持久化存储问题,很多时候还是要看 CSI 控制器日志,而不只是看 Pod 事件。
FAQ
Q: 什么情况下用 emptyDir,什么情况下该上 PVC?
A: 如果数据跟着 Pod 一起消失也没关系,就用 emptyDir;如果数据必须跨 Pod 生命周期保留,就该看 PVC。
Q: Volume 等于备份吗? A: 不等于。Volume 解决的是共享或持久化,备份和恢复仍然要有独立方案。
Q: hostPath 什么时候算坏主意?
A: 在多数需要可移植、可迁移或多租户隔离的环境里,它通常都不是理想方案,因为它和宿主机耦合太深。
下一步阅读
- 接着读
kubernetes-quickstart-pv-pvc.md,理解持久化存储契约 - 再读
kubernetes-quickstart-storageclass.md,理解动态供给和平台侧策略 - 如果要进入有状态工作负载,继续读
kubernetes-quickstart-statefulset.md
收个尾
Volume 相关问题看起来很多,其实第一步通常都很简单:先分清你面对的是“临时数据”还是“持久数据”。这一步一旦想明白,后面的存储设计会顺很多。