Kubernetes 临时卷:emptyDir、缓存和一次性数据
用 emptyDir、内存盘和 Generic Ephemeral Volume 处理缓存、构建空间和 sidecar 共享数据,并理解调度、驱逐和清理边界。
临时卷和 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-storagerequests/limits - 缓存路径固定,清理逻辑可靠
- 构建产物在 Pod 退出前上传
- 日志有轮转或集中采集
- 敏感数据不会写入节点临时文件系统