卷(Volume) 基础
理解 Pod 如何通过 Volume 共享与持久化数据。
容器本身是临时的,Volume 提供了数据共享与持久化的能力,让 Pod 可以保存状态、在容器之间共享文件,并以更安全的方式注入配置。
这篇快速上手在原有基础上补充了常见类型、PVC 申请、StorageClass 选择与排错思路。
为什么需要 Volume
- 容器频繁重启,但业务数据需要持久化。
- 一个 Pod 内多个容器需要共享文件。
- 配置与密钥应以挂载方式注入,而非写入镜像。
常见类型
emptyDir:Pod 生命周期内的临时存储。configMap/secret:配置与密钥注入为文件。persistentVolumeClaim:通过 StorageClass 获取持久存储。hostPath:直接挂载宿主机目录(谨慎使用)。
emptyDir 示例
emptyDir 适合缓存或临时文件:
volumes:
- name: cache
emptyDir: {}
volumeMounts:
- name: cache
mountPath: /cache
你可以用 emptyDir.sizeLimit 限制大小,或使用 medium: Memory 提供内存盘。
ConfigMap 与 Secret 挂载
把配置注入为文件:
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
密钥尽量只读,并避免写入环境变量。
PVC 基础
PVC 通过 StorageClass 申请持久卷:
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
StorageClass 选择
如果集群存在多个 StorageClass,要根据性能与成本选择。数据库常用 SSD 类型,日志或缓存可以选便宜一些的。
kubectl get storageclass
访问模式说明
ReadWriteOnce:最常见,适合数据库。ReadWriteMany:多副本共享文件系统。ReadOnlyMany:只读分发数据。
务必保证访问模式与后端存储能力一致。
多容器共享示例
当一个 Pod 里有 sidecar 需要读取主容器产出的文件时,可以挂载同一个 Volume:
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
这类模式常用于日志收集、内容生成或预处理管道。
有状态工作负载
数据库和消息队列通常需要 PVC 与稳定的 Pod 身份。StatefulSet 能保证稳定的网络名与存储声明。如果把有状态服务放在 Deployment 中,容易出现调度漂移与数据混乱。
生命周期与清理
删除 Pod 不会删除 PVC,这是为保护数据,但也可能造成存储泄露。需要清理时手动删除 PVC,或设置 StorageClass 的 reclaim policy。
备份与迁移建议
Volume 不是备份。数据损坏或节点故障时,需要独立的备份链路。测试环境可以用快照或逻辑备份,生产环境建议制定恢复演练与备份保留策略,并把备份存放到集群外。
当需要更换 StorageClass 时,通常做法是创建新的 PVC,用辅助 Pod 挂载新旧 PVC 进行数据复制,然后切换工作负载到新 PVC。
选型建议
- 临时缓存用
emptyDir。 - 数据库和持久数据必须使用 PVC。
- 避免
hostPath,除非你完全掌控节点并能接受不可移植性。 - 配置与密钥尽量用文件挂载。
- 统一卷命名,方便排错与运维文档维护。
安全注意事项
Volume 挂载意味着文件系统级别共享。配置与密钥尽量用只读挂载,限制写入路径。hostPath 会暴露宿主机文件系统,存在明显安全风险。
多租户环境应结合 PodSecurity 与 RBAC,避免误访问共享存储。涉及敏感数据时,启用存储侧加密与密钥轮换。
常见问题排查
- Pod Pending:PVC 未绑定或缺少 StorageClass。
- 挂载失败:查看 CSI 驱动与节点权限。
- 数据丢失:检查 reclaim policy 与驱逐策略。
- 权限不足:容器用户与卷文件权限不匹配。
- 磁盘满:扩容 PVC(需 StorageClass 支持)。
常用诊断命令:
kubectl describe pod <pod-name>
kubectl describe pvc <pvc-name>
kubectl get pv
更深层的存储问题可查看 kube-system 中 CSI 控制器日志,通常比 Pod 事件更早暴露异常。
性能调优建议
小型集群的本地存储在高 IO 下可能出现延迟抖动。数据库类工作负载建议使用 SSD StorageClass,并根据写入量调整卷容量。
如果有条件,可以用 fio 在测试环境做基线测量,再决定真实工作负载的存储配置。
实操要点
- 先做快速盘点:
kubectl get nodes、kubectl get pods -A、kubectl get events -A。 - 对比“期望状态”和“实际状态”,
kubectl describe往往能解释漂移或失败原因。 - 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。
快速检查清单
- 资源定义与业务意图一致。
- Namespace、权限、镜像与环境匹配。
- 上线前具备健康探针与可观测日志。