先挖坑,再填土


先上结论:Pod 就是一个处在暂停状态的 infra 容器(+ 加入 infra 容器的 namespace 的应用容器)。


介绍

在 k8s 发布以前,只有镜像和容器的概念,伴随着 k8s 的横空出世,才有了 Pod 这个概念。

Pod 是一个逻辑概念,实际在节点上运行的仍然是容器。而多个容器之间如何建立“超亲密关系”,进而成为一组容器,这一组容器又是如何和 Pod 建立对应关系?

这些都要靠一个锚点容器—— infra 容器。

实验

无需运行 k8s 集群,我们可以利用红帽提供的工具 Podman,来近距离观察一下 Pod。

简单介绍一下 Podman,Podman 是红帽容器三件套之一(另两个是 buildah、skopeo),完全对标 docker 命令行工具——如果习惯了敲 docker,可以直接在 shell 的配置中将 docker 设为 podman 的 alias,就可以继续使用 docker 的几乎所有命令形式。

现在,在我刚装的 fedora workstation 35 上,我们用 podman 创建一个 pod,名称设为 test-pod。

podman pod create --name test-pod

有的同学在这里会遇到一个问题,因为我们前面提到 Pod 在容器这一层的锚点是一个 infra 容器,所以创建 Pod 时,首先会创建 infra 容器,infra 容器所用的镜像就是 k8s.gcr.io/pause,连接失败。

如果出现这样的报错,我们可以先从阿里的镜像仓库拉一个 pause 镜像,再 tag 一下就可以了。

podman pull registry.aliyuncs.com/google_containers/pause:3.5
podman tag ed k8s.gcr.io/pause:3.5

Pod 创建完毕,在我们没有运行任何应用的情况下,看到已经创建了一个 pause 容器,并且处于暂停状态。从源码看,pause 容器运行了一个处于睡眠状态的进程。

1个 Pod 可以容纳多个容器运行,这是 Pod 的另一个精髓所在,现在我们往 Pod 里添加一个 nginx 的容器。

接下来对 Pod 中的容器进行清理。尝试使用 podman 直接删除 infra 容器,提示必须先删除 Pod。尝试删除 nginx 应用容器,成功。也就是说,Infra 在 Pod 在,Infra 亡 Pod 亡。

多容器的模式,是一个关注点分离原则的极好实践。infra 容器和具体应用无关,作为 Pod 的锚点、资源的锚点、隔离的锚点,关注平台运维层面的需求。应用可以根据自己的关注点,切分出多个容器,又或者在应用完全不知情的情况下,由第三方直接注入一个容器进来,以非代码侵入的方式抽取信息。

比照 OO 里的设计模式,在 k8s 里也有了 init Container、sidecar、adapter、ambassador 这 4 种结构型设计模式。

在 k8s 里,Pod 作为被管理和调度的基本单位,由 scheduler 负责计算出满足 Pod 要求的节点,并由对应节点上的 kubelet 负责创建 Pod,以实现调度行为。

最后

infra 容器就是 Pod 概念的锚点。

infra 容器的精髓,其实在于 linux 中早就存在的 cgroups、namespace,理论上每个 linux 进程都运行在容器里,属于典型的老树发新芽了。下次再聊聊这个。

软件里对于概念和实体的区分,有时候完全取决于你从哪一个抽象层面去理解。不知周之梦为胡蝶与?胡蝶之梦为周与?


更多:

分类: CODE

1 条评论

ivis · 2023年7月20日 上午12:05

Hey There. I found your blog using msn. This is an extremely well written article. I will be sure to bookmark it and come back to read more of your useful information. Thank you for the post. I will definitely comeback.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注