K8s emptyDir 共享存储卷深度详解|多容器数据互通 + Sidecar 实战
一、前言
学习 K8s Pod 核心知识时,emptyDir 共享存储、多容器数据互通、Sidecar 边车模式是新手最容易混淆、最容易踩坑的重难点。
大家普遍有这些疑惑:
-
同一个 Pod 的多个容器,到底怎么实现数据互通?
-
两个容器的 mountPath 必须一模一样吗?不一样能不能互通?
-
emptyDir 存在哪里?是虚拟的还是节点真实目录?
-
为什么我改了挂载路径,文件明明存在却读不到?
今天结合httpd + busybox 经典 Sidecar 实战 + emptyDir 底层物理原理,一次性讲透,彻底终结所有疑惑!
二、先搞懂:什么是 emptyDir?(底层核心)
emptyDir 是 K8s 最基础的「Pod 级临时共享存储卷」,也是实现 Pod 内容器数据互通的核心手段。
1. emptyDir 核心特性
-
真实物理路径:创建在 Pod 所在 Node 节点本地,真实路径为:
/var/lib/kubelet/pods/xxx/volumes/kubernetes.io~empty-dir/卷名 -
生命周期和 Pod 强绑定:Pod 创建则目录创建,Pod 删除则目录彻底销毁,数据不持久化
-
容器重启不丢数据:仅容器崩溃重启、Pod 不销毁时,emptyDir 数据保留
-
单 Pod 多容器共享:同一个 Pod 内所有容器,可挂载同一个 emptyDir 实现数据互通
-
不跨节点:Pod 漂移到其他节点,会新建 emptyDir,旧数据丢失
2. emptyDir 简单实操验证(查看真实物理路径)
测试 YAML:
apiVersion: v1
kind: Pod
metadata:
name: emptydir
spec:
containers:
- image: httpd
imagePullPolicy: IfNotPresent
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 2G
创建 Pod 后,可登录节点查看 emptyDir 真实存放路径:
# 查看Pod所在节点
kubectl get pod emptydir -o wide
# 登录对应节点,查看容器挂载详情
crictl inspect 容器ID | grep empty-dir
可以清晰看到:所有 emptyDir 数据,最终都落地在节点的 kubelet 目录下。
删除 Pod 后,节点对应目录会自动清空,数据永久丢失。
三、经典实战:httpd + busybox Sidecar 数据互通
1. 实战 YAML(标准生产 Sidecar 模板)
apiVersion: v1
kind: Pod
metadata:
name: sidecarpod
spec:
containers:
# 主业务容器:提供网页访问服务
- name: httpd
image: httpd
volumeMounts:
- name: sidecarvolume
mountPath: /usr/local/apache2/htdocs/
# Sidecar辅助容器:负责写入网页数据
- name: busybox
image: busybox
command: ['sh','-c','echo "Hello Sidecar!" > /usr/local/apache2/htdocs/index.html && sleep 3600']
volumeMounts:
- name: sidecarvolume
mountPath: /usr/local/apache2/htdocs/
# Pod级别:定义共享存储卷
volumes:
- name: sidecarvolume
emptyDir: {}
2. 实验现象
Pod 启动后执行访问测试:
curl <PodIP>
输出结果:
Hello Sidecar!
不再输出 httpd 默认的 It works!,说明 busybox 成功写入文件,httpd 成功读取并展示。
四、核心原理终极通透(解决99%新手误区)
1. 共享卷的真实机制
emptyDir 是整块共享物理存储,Pod 内所有容器挂载它,本质都是映射到节点同一个物理目录。
重点:挂载路径可以不一样,依然能互通!
举例:
-
httpd 挂载:
/cache -
busybox 挂载:
/share
两个路径指向的是同一个物理文件夹,文件可以互相读写,完全互通!
2. 新手最大误区:为什么挂载不同路径读不到网页?
根本不是共享卷的问题,是 httpd 软件本身的限制!
httpd(Apache)程序是写死的:
只认 /usr/local/apache2/htdocs 作为网页根目录,只读取这个目录下的 index.html
举个例子:
-
busybox 挂载到
/tmp,写入/tmp/index.html -
文件真实存在共享卷物理目录中
-
但 httpd 只会读取自身容器内的
/usr/local/apache2/htdocs -
两个路径不匹配,网页读不到内容!
3. 唯一正确的适配逻辑(必背)
想要 Sidecar 成功同步数据给业务容器,必须满足:
辅助容器写入的目录 = 主业务容器读取的目录
所以本次实验必须两边挂载相同路径:/usr/local/apache2/htdocs/
五、三大经典疑惑标准答案(新手必看)
疑问1:访问Apache网页,是不是读取htdocs下的index.html?
是!Apache 默认网页根目录固定为 /usr/local/apache2/htdocs/,访问服务就是读取该目录下的 index.html。
疑问2:两个容器mountPath不一样,能数据互通吗?
能互通!物理数据是共享的!
只是业务程序读取路径固定,不匹配就无法展示业务内容,不是卷不互通!
疑问3:容器内挂载路径不存在,会自动创建吗?
会!K8s 会自动创建容器内不存在的挂载目录,无需手动配置。
六、彻底搞懂 Sidecar 边车模式
本次实验是 K8s 标准 Sidecar 边车模式 最简案例:
-
httpd(主业务容器):专注对外提供网页服务,不做任何数据写入、初始化操作
-
busybox(Sidecar辅助容器):专门负责初始化文件、同步数据、配置更新
核心优势:不侵入主业务代码,解耦业务和辅助操作,广泛用于日志收集、配置同步、动态更新场景。
七、全文终极总结(背下来彻底通透)
-
emptyDir 是 Pod 级临时共享存储,绑定节点真实目录,Pod 删除数据清空
-
共享卷互通核心:volumes 卷名一致即可,mountPath 可以不同
-
业务读不到数据,不是挂载问题,是程序读取目录固定不匹配
-
Sidecar 场景必须统一挂载路径:保证写入目录 = 读取目录
-
Pod 是最小调度单元,内部容器共享存储、共享网络、协同工作
八、学习感悟
之前一直混淆「共享卷互通」和「业务程序读取逻辑」,误以为挂载路径不同就不能互通。通过本次实操排错,彻底弄懂:存储互通是底层机制,业务读取是上层程序逻辑。
搞懂 emptyDir 共享卷和 Sidecar 模式,后续学习配置同步、日志采集、动态更新、有状态服务,全部都能一通百通!
更多推荐


所有评论(0)