一、前言

学习 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辅助容器):专门负责初始化文件、同步数据、配置更新

核心优势:不侵入主业务代码,解耦业务和辅助操作,广泛用于日志收集、配置同步、动态更新场景。

七、全文终极总结(背下来彻底通透)

  1. emptyDir 是 Pod 级临时共享存储,绑定节点真实目录,Pod 删除数据清空

  2. 共享卷互通核心:volumes 卷名一致即可,mountPath 可以不同

  3. 业务读不到数据,不是挂载问题,是程序读取目录固定不匹配

  4. Sidecar 场景必须统一挂载路径:保证写入目录 = 读取目录

  5. Pod 是最小调度单元,内部容器共享存储、共享网络、协同工作

八、学习感悟

之前一直混淆「共享卷互通」和「业务程序读取逻辑」,误以为挂载路径不同就不能互通。通过本次实操排错,彻底弄懂:存储互通是底层机制,业务读取是上层程序逻辑

搞懂 emptyDir 共享卷和 Sidecar 模式,后续学习配置同步、日志采集、动态更新、有状态服务,全部都能一通百通!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐