CFN Cloud
Cloud Future New Life
en zh
2025-10-08 · 0 次浏览

卷(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 nodeskubectl get pods -Akubectl get events -A
  • 对比“期望状态”和“实际状态”,kubectl describe 往往能解释漂移或失败原因。
  • 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。

快速检查清单

  • 资源定义与业务意图一致。
  • Namespace、权限、镜像与环境匹配。
  • 上线前具备健康探针与可观测日志。

参考链接