临时卷和 Pod 生命周期绑定:Pod 删除后数据消失,Pod 迁移后缓存重建。它适合缓存、中间文件、共享日志和构建空间,不适合数据库或必须长期保留的数据。

常见场景

  • 运行时缓存和临时文件
  • 数据处理任务的中间结果
  • sidecar 与主容器共享数据
  • CI 和批处理任务的构建空间

emptyDir 与内存盘

emptyDir 在 Pod 调度到节点时创建,Pod 删除后释放。建议显式设置容量上限:

volumes:
  - name: scratch
    emptyDir:
      sizeLimit: 1Gi

需要更低延迟时可以用内存盘:

emptyDir:
  medium: Memory
  sizeLimit: 512Mi

内存盘占用节点内存,不要把大缓存直接塞进去。内存只适合小而频繁访问的临时数据。

Sidecar 共享

主容器写日志,sidecar 读取或采集:

containers:
  - name: app
    image: my-app:1.0.0
    volumeMounts:
      - name: shared
        mountPath: /var/log/app
  - name: shipper
    image: busybox:1.36
    command: ["sh", "-c", "tail -F /var/log/app/app.log"]
    volumeMounts:
      - name: shared
        mountPath: /var/log/app

共享路径要统一。清理脚本只对固定路径可靠。

构建工作区和缓存预热

CI 或构建任务可以直接把 emptyDir 当工作区:

volumes:
  - name: workspace
    emptyDir: {}
volumeMounts:
  - name: workspace
    mountPath: /workspace

需要保留的构建产物必须在 Pod 退出前上传到对象存储或持久卷。

也可以用 init 容器预热缓存:

initContainers:
  - name: warm-cache
    image: busybox:1.36
    command: ["sh", "-c", "echo warm > /cache/seed.txt"]
    volumeMounts:
      - name: cache
        mountPath: /cache
containers:
  - name: app
    image: my-app:1.0.0
    volumeMounts:
      - name: cache
        mountPath: /cache

Generic Ephemeral Volume

需要更大或更快的工作空间时,Generic Ephemeral Volume 可以通过 StorageClass 创建短期 PVC。PVC 会随 Pod 创建和删除:

volumes:
  - name: cache
    ephemeral:
      volumeClaimTemplate:
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: fast-ssd
          resources:
            requests:
              storage: 5Gi

它适合批处理和短期任务;长期数据仍应使用 PVC 或数据库存储。

把临时存储当预算管理

emptyDir.sizeLimit 是 kubelet 层面的软限制,超过后可能触发驱逐。调度器还需要 ephemeral-storage requests/limits 才能准确放置 Pod:

resources:
  requests:
    cpu: "100m"
    memory: "256Mi"
    ephemeral-storage: "1Gi"
  limits:
    cpu: "500m"
    memory: "512Mi"
    ephemeral-storage: "2Gi"

容器日志也计入节点临时存储。没有日志轮转和集中采集的集群,磁盘压力通常比应用缓存先出现。

观察磁盘压力和驱逐

Pod 频繁驱逐时,先看节点和事件,而不是只看应用日志:

kubectl describe pod <pod-name>
kubectl get events -A
kubectl describe node <node> | rg -n "ephemeral-storage|Allocatable"
kubectl top pod -A

也可以在 Pod 内确认文件系统使用量:

kubectl exec -it <pod-name> -- df -h

安全边界

临时卷位于节点文件系统,不要写入敏感数据。涉及合规数据时,优先避免写入;必须使用时,先加密,再限制到内存盘和小容量。

不适合临时卷的场景

  • 数据库或必须跨 Pod 重启保留的数据
  • 审计日志或合规留存数据
  • 用户上传文件

常见问题

Q:Pod 为什么 Pending? A:节点临时存储不足,或者 Pod 的 ephemeral-storage 请求无法满足。

Q:Pod 为什么 Evicted? A:通常是节点磁盘压力。检查临时卷、日志和镜像缓存占用。

Q:emptyDir.sizeLimit 生效后为什么还能影响节点? A:它是软限制。没有显式 limits 时,kubelet 可能在节点压力后驱逐 Pod。

Q:Generic Ephemeral 和 PVC 怎么选? A:随 Pod 生命周期创建删除的数据用 Generic Ephemeral;需要长期保留的数据用普通 PVC。

落地前检查

  • emptyDir 设置了 sizeLimit
  • 容器设置了 ephemeral-storage requests/limits
  • 缓存路径固定,清理逻辑可靠
  • 构建产物在 Pod 退出前上传
  • 日志有轮转或集中采集
  • 敏感数据不会写入节点临时文件系统

参考链接