图解 K8S(03):从 Pause 容器理解 Pod 的本质

标签: Kubernetes Github Google Mac 博客 | 发表时间:2022-01-29 20:46 | 作者:王炳明
出处:https://iswbm.com

在 K8S 中,Pod 是最核心、最基础的资源对象,它是 Kubernetes 中调度最小单元,学习 K8S 很多时候,我们都是在跟 Pod 打交道,它的内容是最多的,需要分好多的章节才能将它讲透。

本篇作为 Pod 的首篇,打算先从咱们熟悉的 Docker 容器入手,介绍 Pod 的组成及其工作原理。

主要解决几个关键问题:

  1. Pod 是什么?它与容器是什么关系?
  2. 为什么 K8S 不直接管理容器呢?

1. Pod 与 容器的关系

都说 K8S 是容器编排引擎,那怎么 K8S 中最小的可管理可部署的计算单元是 Pod 而不是容器呢?

Pod 和 容器,又是什么关系呢?

其实 Pod 只是一个抽象的逻辑概念,它是一组(一个或者多个)容器的集合,这些容器之间共享同一份存储、网络等资源。

使用 kubectl get po -o wide可以查看 pod 的列表,其中 READY 列代表该 Pod 总共有 1 个容器,并且该容器已经成功启动,可以对外提供服务了

登陆到该 Pod 年在到 worker 节点上,使用 docker ps 查看容器

咦?上面不是说该 Pod 只有一个容器吗?怎么这个 grep 出来,却有两个呢?

实际上,这个 pause 容器,是一个很特殊的容器,它又叫 infra 容器,是每个 Pod 都会自动创建的容器,它不属于用户自定义的容器。

那么这个 pause 容器有什么用呢?

接下来就来说说 pause 诞生的背景,它对 Pod 模型的理解有非常重要的意义。

2. Pause 容器

pause 容器镜像

使用 docker insepct [CONTAAINER_ID] 查看一下 pause 容器的详情信息,可以发现 pause 容器使用的镜像为

  registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6

该镜像非常小,只有 484KB,由于它总是处于 Pause (暂时)状态,所以取名叫 pause

想了解该 pause 容器的构成(代码是用 C 语言写的)的可以去官方仓库上一看究竟:https://github.com/kubernetes/kubernetes/tree/master/build/pause

pause 容器作用

上面我们说,一个 Pod 是由一组容器组成的,这些容器之间共享存储和网络资源,那么网络资源是如何共享的呢?

假设现在有一个 Pod,它包含两个容器(A 和 B),K8S 是通过让他们加入(join)另一个第三方容器的 network namespace 实现的共享,而这个第三方容器就是 pause 容器。

2-2-2 Infra/Pause Container

这么做的目的,其实很简单,想象一下,如果没有这样的第三方容器,会发生怎样的结果?

没有 pause 容器,那么 A 和 B 要共享网络,要不就是 A 加入 B 的 network namespace,要嘛就是 B 加入 A 的 network namespace, 而无论是谁加入谁,只要 network 的 owner 退出了,该 Pod 里的所有其他容器网络都会立马异常,这显然是不合理的。

反过来,由于 pause 里只有是挂起一个容器,里面没有任何复杂的逻辑,只要不主动杀掉 Pod,pause 都会一直存活,这样一来就能保证在 Pod 运行期间同一 Pod 里的容器网络的稳定。

我们在同一 Pod 里所有容器里看到的网络视图,都是完全一样的,包括网络设备、IP 地址、Mac 地址等等,因为他们其实全是同一份,而这一份都来自于 Pod 第一次创建的这个 Infra container。

由于所有的业务容器都要依赖于 pause 容器,因此在 Pod 启动时,它总是创建的第一个容器,可以说 Pod 的生命周期就是 pause 容器的生命周期。

3. 手工模拟 Pod

从上面我们已经知道,一个 Pod 从表面上来看至少由一个容器组成,而实际上一个 Pod 至少要有包含两个容器,一个是业务容器,一个是 pause 容器。

理解了这个模型,我们就可以用以前熟悉的 docker 容器,手动创建一个真正意义上的 Pod。

2-2-3 Faker Pod via Docker

创建 pause 容器

使用 docker run 加如下参数:

  • --name:指定 pause 容器的名字,fake_k8s_pod_pause
  • -p 8888:80:将宿主机的 8888 端口映射到容器的 80 端口

创建 nginx 容器

创建容器之前先准备一下 nginx.conf 配置文件

然后运行如下命令创建名字 fake_k8s_pod_nginx 的 nginx 容器

其中 -v 参数是将宿主机上的 nginx.conf 文件挂载给 nginx 容器

除此之外,还有另外三个核心参数:

  • --net:指定 nginx 要 join 谁的 network namespace,当然是前面创建的fake_k8s_pod_pause
  • --ipc:指定 ipc mode, 一样指定前面创建的fake_k8s_pod_pause
  • --pid:指定 nginx 要 join 谁的 pid namespace,照旧是前面创建的fake_k8s_pod_pause

创建 ghost 容器

有了 nginx 还不够,还需要有人提供网页的数据,这里使用 ghost 这个博客应用,参数和上面差不多,这里不再赘述。

到这里,我就纯手工模拟出了一个符合 K8S Pod 模型的 “Pod” ,只是它并不由 K8S 进行管理。

这个 “Pod” 由一个 fake_k8s_pod_pause 容器(负责提供可稳定共享的命名空间)和两个共享 fake_k8s_pod_pause 容器命名空间的两业务容器。

访问 “Pod” 服务

由于我是在 worker (ip 为 172.20.20.11)节点上创建的 “Pod”,因此在我的 Mac 电脑上,直接访问 http://172.20.20.11:8888/ 就可以访问该博客啦

4. 创建真正的 Pod

上一节,我在 K8S 生态之外,单纯使用 Docker 创建了三个容器(Pause、Nginx、Ghost),这三个容器的的组合,在 K8S 中称之为 Pod。

2-2-4 Faker Pod via Docker

如果没有 K8S 的 Pod ,你启动一个 ghost 博客服务,你需要手动创建三个容器,当你想销毁这个服务时,同样需要删除三个容器。

而有了 K8S 的 Pod,这三个容器在逻辑上就是一个整体,创建 Pod 就会自动创建三个容器,删除 Pod 就会删除三个容器,从管理上来讲,方便了不少。

这正是 Pod 存在的一个根本意义所在。

那到底有多方便呢?还是以上面 ghost 博客为例,下面我会介绍如何 K8S 中创建一个像上面一样的博客应用?

创建 ConfigMap

ConfigMap 也是 K8S 中的一个对象,目前还没有学到,你只要知道它是一个用来存储信息的对象即可

使用如下命令即可创建一个 ConfigMap 对象,用它来存储 nginx.conf 文件。

  kubectl create configmap nginx-config --from-file=nginx.conf

使用 -o yaml 参数,就能看到 nginx.conf 文件中的内容。

创建 Pod

接着执行如下命令创建一个 ghost.yaml 文件(yaml 文件内容,在文末获取)

然后直接 apply 该文件就可以创建一个 ghost 服务,从输出可以看到这里的 READY 变成了 2/2,意思是该 Pod 总共包含 2 个容器,目前已经全部准备就绪。

此时再去访问 http://172.20.20.11:8888/ 一样可以访问博客页面

5. 总结一下

本文以 pause 容器为突破口,在脱离 K8S 生态之下,使用 docker 手工创建具有业务相关的多个容器,模拟出最初的 Pod 模型,理解了这个基本就对 Pod 的意义有了一个直观、深刻的认识。

相关 [k8s pause 容器] 推荐:

图解 K8S(03):从 Pause 容器理解 Pod 的本质

- - 明哥教程
在 K8S 中,Pod 是最核心、最基础的资源对象,它是 Kubernetes 中调度最小单元,学习 K8S 很多时候,我们都是在跟 Pod 打交道,它的内容是最多的,需要分好多的章节才能将它讲透. 本篇作为 Pod 的首篇,打算先从咱们熟悉的 Docker 容器入手,介绍 Pod 的组成及其工作原理.

K8S的SDN容器网络解决方案及其价值

- - SegmentFault 最新的文章
编者按:关于容器网络的解决方案业界已经有较多的讨论,笔者无意继续赘述. K8S及其网络模型体现了鲜明的解耦设计思想,采用SDN技术实现K8S容器网络,并与相应的生态组件形成SDN监管控一体化解决方案,可以更好地提高整个系统的运营水平,更有效地提升企业的核心竞争力. 本文拟抛砖引玉,从K8S的网络实现入手,重点阐述SDN在容器网络中的应用价值.

K8S/Docker中对于容器内存的监控 (www.ipcpu.com)

- - IT瘾-jianshu
在使用Docker或者Kubernetes时,我们经常需要监控容器或者Pod的内存,同时我们也经常收到反馈内存不准确的情况,这不仅是因为存在Buffer、Cache的影响,不同的算法指标也会得出不同的结果. 接下来我们先回顾下我们最古老的计算方法,然后分别取分析docker stats 和 kubectl top 中的内存计算方法.

如何收集K8S容器化部署的服务的日志?

- - 掘金 后端
做开发的同学都知道日志的重要性,日志的种类一般有接口日志、错误日志、关键步骤日志、用户操作日志等. 本文主要详细讲解使用kubernetes容器化部署的服务该如何记录和收集日志. 将想要记录的日志内容输出到stdout或stderr即可(DockerEngine本身具有LogDriver 功能,可通过配置不同的LogDriver将容器的stdout通过DockerEngine写入到日志系统),由DockerEngine将日志写入到日志系统.

K8s 的核心是 API 而非容器:从理论到 CRD 实践(2022)

- - ArthurChiao's Blog
本文串联了以下几篇文章的核心部分,. 论述了 K8s 的核心价值是其通用、跨厂商和平台、可灵活扩展的声明式 API 框架, 而不是容器(虽然容器是它成功的基础);然后手动创建一个 API extension(CRD), 通过测试和类比来对这一论述有一个更直观的理解. 例子及测试基于 K8s v1.21.0,感谢原作者们的精彩文章.

CentOS7 安装 K8S

- - 企业架构 - ITeye博客
前提:VirtualBox CentOS7. 物理机IP   192.168.18.8. 虚拟机1IP:192.168.18.100(VMaster master). 虚拟机2IP:192.168.18.101(VServer1 node1). 虚拟机3IP:192.168.18.102(VServer2 node2).

容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?(上)-社区博客-网易云

- -
无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker. 如果使用容器,应该使用哪个容器平台. 显而易见,我不会直接给大家一个答案,而是希望从技术角度进行分析具体的场景. 例如客户是大公司还是小公司,将部署小集群还是大集群,倾向于私有云还是公有云,已经采购了 IaaS 还是没有 IaaS,IT 运维能力强还是弱,是否需要物理机、虚拟机、容器的混合部署,是一般的并发系统还是高并发,这里面所应该做的技术选型都不一样.

k8s水平扩容

- - Bboysoul's Blog
k8s 的好处就是可以弹性水平扩容和纵向扩容,平时纵向扩容用的不太多,所以今天说说水平扩容,在创建hpa之前你要确定集群中已经安装了metrics-server,我使用的是k3s,直接自带. 首先创建需要的容器,下面是dockerfile. 原理就是当你访问index.php的时候会进行一个循环计算来提高cpu的使用率.

# [k8s] HPA: Horizontal Pod Autoscaling

- - V2EX - 技术
HPA 是 K8S 的一大利器. 通过 HPA, 我们可以让服务的 pod 数量根据特定指标自动增加或减少, 使得在高峰期有足够的资源服务请求, 在低峰期又可以避免占用过多的资源. 同时, 在 SOA 架构下, 我们也习惯通过 HPA 来避免劳心劳力的为每个微服务计算所需的资源.. minReplicas: 允许的最小 pod 数量.

K8S 1.24.0 安装部署

- - Share
在 v1.2x 版本中, Kubernetes 支持的最大节点数为 5000. 更具体地说,我们支持满足以下所有条件的配置:. 每个节点的 pod 数量不超过. Kubernetes v1.20 开始,默认移除 docker 的依赖,如果宿主机上安装了 docker 和 containerd,将优先使用 docker 作为容器运行引擎,如果宿主机上未安装 docker 只安装了 containerd,将使用 containerd 作为容器运行引擎;.