Pause容器是干什么的?

1.简介

Pod是K8s最小的调度单元,但它的内部结构却充满了许多复杂的机制,其中之一就是Pause容器。尽管Pause容器看似不起眼,但它在整个K8s集群中发挥了至关重要的作用。我们在 kubernetes 的 node 节点,执行 docker ps,可以发现每个 node 上都运行了一个 pause进程的容器,如下:

[root@k8s-worker01 ~]# docker ps |grep nginx
66032431a20e   2ae1addee1b2                                                     "/entrypoint.sh --…"   30 hours ago     Up 30 hours               k8s_nginx_nginx-68b9ccfc77-x8sqg_nginx_aa5b97bf-3db8-4b92-89a7-1fe551645e6a_0
10d393461904   registry.aliyuncs.com/google_containers/pause:3.5                "/pause"                 30 hours ago     Up 30 hours               k8s_POD_nginx-68b9ccfc77-x8sqg_nginx_aa5b97bf-3db8-4b92-89a7-1fe551645e6a_0

为什么使用 kubectl create 或 kubectl apply 等命令创建Pod时,不会看到Pause容器。这是因为Pause容器是由Kubernetes自动创建和管理的,通常不需要用户手动操作或关注。它是Pod的一个组成部分,用于维护Pod的基础设施和容器之间的网络隔离。

有的时候,出现的报错如下:

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "k8s.gcr.io/pause:3.5": failed to pull image "k8s.gcr.io/pause:3.5": failed to pull and unpack image "k8s.gcr.io/pause:3.5": failed to resolve reference "k8s.gcr.io/pause:3.5": failed to do request: Head "https://k8s.gcr.io/v2/pause/manifests/3.5": x509: certificate signed by unknown authority

这是因为 k8s.gcr.io 这个地址是需要连外网才可以拉取到,导致 pause 镜像拉不下来,Pod无法启动。

当你使用docker ps时,你会发现有很多 pause 容器运行于服务器上面,容器命名也很规范,然后每次启动一个容器,都会伴随一个pause这样的容器启动。那它究竟是干啥子的?它就是 Pause 容器,又叫 Infra 容器。

查看 kubelet 进程,可以看到配置中有这样一个参数:

将参数“--pod-infra-container-image”,设置为:“registry.aliyuncs.com/google_containers/pause:3.5”

[root@k8s-worker01 ~]# ps -ef|grep kubelet
root      5678     1 10 Sep18 ?        01:15:07 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5
[root@k8s-worker01 ~]# docker images|grep pause
registry.aliyuncs.com/google_containers/pause                     3.5        ed210e3e4a5b   2 years ago     683kB

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

2.作用

2.1 进程隔离

Pause容器保持一个轻量级的进程运行,即使Pod中的其他容器都停止了。这个进程实际上不执行任何有用的工作,但它的存在确保了Pod不会在没有容器运行的情况下被删除。当其他容器停止时,Pause容器仍在运行,以维持Pod的生命周期。

2.2 资源隔离

尽管Pause容器通常不分配大量的CPU和内存资源,但它可以配置以使用一些资源。这有助于确保即使Pod中没有其他容器运行时,Kubernetes仍然可以监控和管理Pod的资源使用情况。这也有助于防止Pod被其他具有相同资源要求的Pod占用。

2.3 网络隔离

Pod是Kubernetes中最小的调度单元,可以包含一个或多个容器。为了实现容器之间的网络隔离,每个Pod都有自己独立的网络命名空间。Pause容器负责创建并维护这个网络命名空间,其他容器共享这个网络命名空间,使它们能够相互通信,而不会与其他Pod中的容器发生冲突,Pause容器负责维护Pod的IP地址。Pod的IP地址通常是动态分配的,但由于Pause容器一直在运行,它可以维护Pod的IP地址,以便其他容器可以通过该地址进行通信。这有助于确保Pod的IP地址在整个Pod的生命周期内保持一致。

2.4 生命周期管理

Pause容器的生命周期与Pod的生命周期相同。当Pod创建时,Pause容器被创建;当Pod删除时,Pause容器也会被删除。这确保了Pod的整个生命周期都由Kubernetes进行管理,包括创建、扩展、缩放和删除。

 

3.工作方式

下面例子:

核心功能:

  • 第一,它提供整个pod的Linux命名空间的基础。
  • 第二,启用PID命名空间,它在每个pod中都作为PID为1的进程,并回收僵尸进程。

现在有一个 Pod,其中包含了一个容器 A 和一个容器 B,它们两个就要共享 Network Namespace。在 Kubernetes 里的解法是这样的:它会在每个 Pod 里,额外起一个 Infra container 小容器来共享整个 Pod 的 Network Namespace。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。所以说一个 Pod 里面的所有容器,它们看到的网络视图可以说是完全一样的。这就是 Pod 的网络实现方式。由于需要有一个相当于说中间的容器存在,所以整个 Pod 里面,必然是 Infra container 第一个启动。并且整个 Pod 的生命周期是等同于 Infra container 的生命周期的,与容器 A 和 B 是无关的。这是非常重要的一个设计。