IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在前面的文章中,我们用 Volume 为 Redis 持久化了数据,用 ConfigMap 和 Secret 注入了配置文件。你可能会觉得,K8s 的存储已经够用了。但如果我问你:Pod 里的多个容器如何共享临时文件?如何让容器访问宿主机上的特定目录或文件?
这两个场景,K8s 提供了两种最基础的存储卷类型来解决:emptyDir 和 hostPath。它们是所有 K8s 存储中最简单的两种类型,也是理解更复杂的 PV/PVC(下一篇主题)的前置知识。
一、emptyDir:Pod 级别的临时存储
1.1 什么是 emptyDir?
emptyDir 是 Kubernetes 中最简单的卷类型。它的生命周期和 Pod 绑定------Pod 创建时自动创建一个空目录,Pod 删除时该目录连同里面所有数据被永久删除。
emptyDir 的核心用途是让同一个 Pod 内的多个容器共享文件。它的存储位置可以是节点的磁盘(默认),也可以配置为 tmpfs 存储在内存中以提高 IO 性能。
emptyDir 的三个关键特性:
-
Pod 级别生命周期:随 Pod 创建,随 Pod 删除。容器重启不影响 emptyDir 中的数据。
-
同 Pod 内共享:Pod 内所有容器都可以读写该目录。
-
节点本地存储:数据存储在 Pod 所在节点的磁盘上,不会跟随 Pod 迁移到其他节点。
在第 23 篇 Sidecar 模式实战中,我们其实已经用过 emptyDir------volumes: - name: shared-logs emptyDir: {} 让 Flask 主容器和日志采集 Sidecar 共享日志目录。当时我们只演示了用法,没有深挖它为什么是 emptyDir 而不是其他类型。
1.2 动手验证 emptyDir 的基本行为
下面的 YAML 定义一个 Pod,包含一个写入数据的容器和一个读取数据的容器:
bash
apiVersion: v1
kind: Pod
metadata:
name: emptydir-demo
spec:
containers:
- name: writer
image: alpine
command: ["sh", "-c", "echo 'shared data' > /cache/demo.txt && sleep 3600"]
volumeMounts:
- name: shared-cache
mountPath: /cache
- name: reader
image: alpine
command: ["sh", "-c", "sleep 10 && cat /data/demo.txt && sleep 3600"]
volumeMounts:
- name: shared-cache
mountPath: /data
volumes:
- name: shared-cache
emptyDir: {}
这个 Pod 包含两个容器:writer 和 reader。它们通过 shared-cache 这个 emptyDir 卷共享文件。writer 写入 /cache/demo.txt,reader 从 /data/demo.txt 读取------两个容器内路径不同,但底层是同一个空目录。
部署并验证:
bash
kubectl apply -f emptydir-demo.yaml
kubectl logs emptydir-demo -c reader
# shared data
reader 成功读到了 writer 写入的内容,这就是 emptyDir 实现的多容器文件共享。
1.3 emptyDir 的常见使用场景
场景一:Sidecar 模式中的文件交换
Flask 容器写日志到 /app/logs,Filebeat Sidecar 从 /var/log/flask 读取并转发。两个路径指向同一个 emptyDir 卷。
场景二:临时排序/计算空间
数据处理任务需要大量临时磁盘空间(如排序大文件),使用 emptyDir 作为临时工作目录。任务结束后 Pod 自动清理,不会留下垃圾文件。
场景三:共享缓存
一个容器下载数据,另一个容器处理数据。通过 emptyDir 共享,避免网络传输开销。
1.4 将 emptyDir 存储在内存中(tmpfs)
默认 emptyDir 使用节点磁盘。对于需要高 IO 性能且不介意丢失数据的场景,可以将其配置为内存存储:
bash
volumes:
- name: fast-cache
emptyDir:
medium: Memory
sizeLimit: 256Mi
-
medium: Memory:数据存储在 tmpfs(内存文件系统)中,读写速度远快于磁盘 -
sizeLimit: 256Mi:限制最大使用内存,防止某个 Pod 过度消耗节点内存
场景对比 :medium: Memory 适合需要高 IOPS 的临时计算(如机器学习训练中的中间特征存储),普通磁盘 emptyDir 适合日志、临时文件等 IO 要求不高的场景。内存 emptyDir 的数据在容器重启后仍然保留(因为 tmpfs 生命周期跟随 Pod),但 Pod 被删除或节点重启时数据会丢失。
二、hostPath:访问宿主机文件系统
2.1 什么是 hostPath?
hostPath 卷将宿主机(Node)文件系统上的一个特定目录或文件直接挂载到 Pod 中。与 emptyDir 不同,hostPath 的数据在 Pod 删除后依然保留在宿主机上,并且同一节点上的多个 Pod 可以挂载同一个宿主机路径来共享数据。
hostPath 的核心特性是绕过了容器的文件系统隔离,让 Pod 能够直接读写宿主机目录。这使得它能够用于运行需要访问宿主机资源的集群级组件,但也带来了更强的节点依赖性。
在第 27 篇部署 DaemonSet 时,我们演示过 hostPath------Node Exporter 通过 hostPath 挂载宿主机的 /proc 和 /sys 来采集系统指标。那是 hostPath 最经典的用法。
2.2 hostPath 的类型
hostPath 通过 type 字段定义路径的存在性要求,这决定了 kubelet 在挂载前的检查行为:
2.3 hostPath 的三大典型场景
场景一:访问容器运行时数据
bash
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
type: Socket
这是容器监控工具(如 cAdvisor、Prometheus)访问 Docker 运行时的常用配置。但这也存在严重的安全风险------容器获得了控制宿主机 Docker 引擎的能力。
场景二:节点级日志或配置文件访问
bash
volumes:
- name: node-logs
hostPath:
path: /var/log
type: Directory
Logging Agent 通过这种方式采集宿主机上所有容器的日志。
场景三:DaemonSet 部署的集群组件
Node Exporter 通过 hostPath 挂载 /proc、/sys 采集系统指标;CNI 网络插件通过 hostPath 管理网络配置文件。
2.4 hostPath 的使用限制与安全风险
hostPath 在提供便利的同时,也带来了三个主要风险:
-
节点依赖性 :Pod 被调度到不同节点时,宿主机目录内容可能完全不同,导致 Pod 行为不可预测。hostPath 通常与
nodeSelector或nodeName配合使用,将 Pod 绑定到特定节点。 -
安全风险 :
DirectoryOrCreate如果创建的目录父目录属于 root,kubelet 会以 root 身份创建目录,可能导致权限问题。挂载敏感路径(如/var/run/docker.sock)相当于赋予了容器控制宿主机的权限。 -
资源监控困难:hostPath 的磁盘使用量不会被 K8s 自动监控和限制,Pod 可能无意中填满节点磁盘。
最佳实践 :对于普通应用,优先使用 emptyDir(临时共享)或 PV/PVC(持久化)。hostPath 应限制在 DaemonSet 部署的集群组件,并且永远不要在 hostPath 中挂载 docker.sock 给不信任的容器。
三、emptyDir vs hostPath vs PV/PVC
在进入更复杂的存储体系之前,我们先建立这三个概念的清晰边界:
emptyDir 和 hostPath 都是节点级别的存储,Pod 一旦漂移到其他节点就无法访问原来的数据。对于数据库这类需要真正持久化的应用,必须使用 PV/PVC。这正是下一篇要解决的问题。
四、命令速查表
五、本篇总结
-
emptyDir 是 Pod 级的临时存储,适用于多容器间的文件共享和临时数据处理。分为磁盘型和内存型(tmpfs)。
-
hostPath 是节点级存储,将宿主机目录挂载到容器,适用于需要访问宿主机资源的集群组件。使用时需特别注意安全和节点依赖性。
-
两者都不是持久化存储------Pod 删除或漂移到其他节点后,数据可能丢失。对于需要跨节点持久化的数据,必须使用 PV/PVC。
理解了 emptyDir 和 hostPath,你就掌握了 K8s 存储体系中"临时"和"节点绑定"这两类场景的工具。下一篇------第 35 篇:PVC 与 StorageClass:动态存储供应,我们将进入 K8s 存储体系的核心,学习如何用 PVC 和 StorageClass 为应用提供真正的持久化、跨节点的存储能力。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !