Pause容器的作用

pause容器,又叫Infra容器,是pod的基础容器,镜像体积只有几百KB左右,配置在kubelet中,主要的功能是使一个pod中多个容器的网络通信

我们看下在node节点上都会起很多pause容器,和pod是一一对应的。每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中。同一个Pod里的容器之间仅需通过localhost就能互相通信。

kubernetes中的pause容器主要为每个业务容器提供以下功能:

PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
UTS命名空间:Pod中的多个容器共享一个主机名;
Volumes(共享存储卷):Pod中的各个容器可以访问在Pod级别定义的Volume

Infra容器被创建后会初始化Network Namespace,之后其他容器就可以加入到Infra容器中共享Infra容器的网络了 ,因此如果一个pod中的两个容器A和B,那么关系如下:

1、A容器和B容器能够直接用localhost通信;

2、A容器和B容器可以看到网卡、IP与端口监听信息;

3、Pod只有一个IP地址,也就是该Pod的Network Namespace对应的IP地址(由Infra容器初始化并创建)。

4、K8s环境中的每个Pod有一个独立的IP地址(前提是地址足够用),并且此IP被当前Pod中所有容器在内部共享使用。

5、Pod删除后Infra容器随机被删除。其IP被回收。

Pause容器共享的Namespace

1、NET Namespace: Pod中的多个空器共享同一个网络命名空间。即使用相同的IP和端口信息

2、IPC Namespace: pod中的多个容器可以使用System V IPCak POSIX消息队列进行通信

3、UTS Namespace: pod中的多个容器共享一个主机名

MNT Namespace、PID Namespace、User Namespace未共享

三个容器的运行

我们在kubelet的配置文件中心都指定了如下参数,这是指定拉取的pause镜像地址。

systemctl status kubelet -l
/usr/bin/kubelet --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig --kubeconfig=/opt/kubernetes/cfg/kubelet.conf --config=/opt/kubernetes/cfg/kubelet-config.yml --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.4.1
docker ps | grep pause 查看所有的pause容器
docker images | grep pause 查看所有的pause镜像

如下图所示:

我们首先在节点上运行一个pause容器。

docker run -d --name pause -p 8880:80  --ipc=host registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1

然后再运行一个nginx容器,

docker run -d --name nginx  --net=container:pause  --pid=container:pause --ipc=container:pause  nginx

然后再为ghost创建一个应用容器,这是一款博客软件。

docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost

pause容器将内部的80端口映射到宿主机的8880端口,pause容器在宿主机上设置好了网络namespace后,nginx容器加入到该网络namespace中,我们看到nginx容器启动的时候指定了–net=container:pause,ghost容器同样加入到了该网络namespace中,这样三个容器就共享了网络,互相之间就可以使用localhost直接通信,–ipc=contianer:pause --pid=container:pause就是三个容器处于同一个namespace中,init进程为pause,这时我们进入到ghost容器中查看进程情况。

root@weizhibiao:~# docker exec -it ghost bash
root@cfa367869c60:/var/lib/ghost# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:12 ?        00:00:00 /pause
root       756     0  0 13:37 ?        00:00:00 nginx: master process nginx -g daemon off;
101        785   756  0 13:37 ?        00:00:00 nginx: worker process
node       786     0  2 13:37 ?        00:00:08 node current/index.js
root      1181     0  0 13:41 pts/0    00:00:00 bash
root      1495  1181  0 13:42 pts/0    00:00:00 ps -ef
root@cfa367869c60:/var/lib/ghost# 

上面这个代码用来展示,同一个pod里面的容器,可以看到相互之间的进程。

在ghost容器中同时可以看到pause和nginx容器的进程,并且pause容器的PID是1。而在kubernetes中容器的PID=1的进程即为容器本身的业务进程。

总结

pause容器是为了解决同一个pod里面的container通信的问题。
在docker中,每个container本来就至少隶属于一个 网络命名空间/网关/bridge,所以有一个 ip .
但是在k8s中,每个container都是使用 pause 的ip 这个network ns网络命名空间的ip

k8s中,创建一个pod后。pause容器创建一个网络命名空间,此pod的容器共享这个网络命名空间。本质上,pause容器用来完成 同一个pod下面的container的通信,这个通过 docker network 同一个网络命名空间/网关/bridge 的底层知识来实现的,而 docker network 同一个网络命名空间的通信又是通过 linux 底层的 veth-pair 键值对来完成 , 即 container1 <-> linux <-> container2

参考资料:https://blog.csdn.net/weixin_40579389/article/details/125941366
参考:https://blog.51cto.com/yht1990/5841893

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐