背景: 最近在实现 Kata containers 的 sandbox 级共享 volume 的时候,需要使用 crictl 模拟 emptydir 进行测试,但是搜了很多资料并没有指出如何使用 crictl 模拟 emptydir 的教程,在看了 Kubernetes 的实现原理之后,在这篇文章总结下。
先说下 Kubernetes 是如何处理 emptydir 的,在官方文档中已经给出了一个例子,指出 emptydir 是一个匿名的和 pod 同生命周期的 volume。Sandbox 在 runc 中是一个 infra container,在 kata 中是一个 vm,换句话说 sandbox 本身是不能挂载目录的。
不卖关子,emptydir 就是一个普通的 volume,但是是由 kubelet 控制的,保证 emptydir 的生命周期与 pod 保持一致。如果 crictl 需要模拟 emptydir,理论上我们需要模拟 kubelet 的行为。但是我们看 OCI runtime mount 的数据结构,并没有任何有关 emptydir 的配置参数,那么容器是如何识别 emptydir 的呢?
我之后去看了下 kata 以及 k8s 的源码,emptydir 具有特殊的文件路径结 "{basePath}/kubernetes.io~empty-dir/{name}",其中:
- basePath: 一般是由 kubelet 管理的一个临时文件夹路径。
- kubernetes.io~empty-dir: 这是一个固定值(literal),容器就是通过识别这个值确定当前的 volume 是否属于一个 emptydir。
- name: 表示这个 emptydir 的名字。
基于上述事实,使用 crictl 模拟 emptydir 的步骤是:
- 按照上述文件结构手动创建一个 source 路径,比如 "/tmp/kata-containers/volumes/kubernetes.io~empty-dir/test"。
- 为 container 创建一个配置文件 container-config.json。
- 按照正常的方式以此使用 crictl 创建 pod 和 container。
使用 emptydir 时需要注意的是:
While a Pod is running its emptyDir exists. If a container in a Pod crashes the emptyDir content is unaffected. Deleting a Pod deletes all its emptyDirs.
当 pod 结束的时候,emptydir 中的数据会被 kubelet(cri) 强制清空。