k8s中pause容器作用

k8s中pause容器作用NAME READY STATUS RESTARTS AGE IP NODE

大家好,欢迎来到IT知识分享网。

k8s中pause容器作用

现象

在k8s中生成中每当我们创建一个pod,都会伴随着一个pause容器产生,因此我们在node上面有很多的pause容器。

例如:

# master节点 [root@test-3-217 ~]# kubectl apply -f busybox.yaml [root@test-3-217 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES busybox-pod 1/1 Running 0 30m 10.244.2.45 test-3-219 <none> <none> # node节查看busybox容器 [root@test-3-219 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0969c 1c35c "sleep 3600" 52 seconds ago Up 50 seconds k8s_busybox_busybox-pod_default_ec874d6b-9d08-4a16-8f48-e22fd8bfca0a_0 434df7bbc3fb registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 "/pause" 53 seconds ago Up 51 seconds k8s_POD_busybox-p

由上可以看出,pause是一个容器,但不是pod,而且先于busybox容器产生,那么pause容器有什么作用呢?

在kubernetes中,pod是可以创建和管理的最小单元,由一个或多个相关联的容器组成。pod中的多个容器共享同一个网络命名空间,因此这些容器可以共享pod的IP和端口。

其中共享的网络名称apche就是通过pause容器实现的。

下面我们通过创建一个由nginx,ghost,busybox组成的pod来演示下。

pause功能演示network namesapce

1.创建pod资源

# 配置文件 vim pause-test.yaml apiVersion: v1 kind: Pod metadata: name: pause-test spec: containers: - name: busybox command: - sleep - "3600" image: busybox imagePullPolicy: IfNotPresent - name: ghost image: ghost:3.21 imagePullPolicy: IfNotPresent - name: nginx image: nginx:1.9.1 imagePullPolicy: IfNotPresent restartPolicy: Always # 运行 kubectl apply -f pause-test.yaml # 查看pod [root@test-3-217 pause]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pause-test 3/3 Running 3 3h11m 10.244.2.49 test-3-219 <none> <none> # 查看容器 [root@test-3-219 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2d9d8566b53f 1c35c "sleep 3600" 22 minutes ago Up 22 minutes k8s_busybox_pause-test_default_02e7dcb7-5aeb-477f-a50b-74ce1b0a7704_3 9d8ccf485b8f 94ec7e53edfc "nginx -g 'daemon of…" 3 hours ago Up 3 hours k8s_nginx_pause-test_default_02e7dcb7-5aeb-477f-a50b-74ce1b0a7704_0 faa2fb108ab3 dbd2e "docker-entrypoint.s…" 3 hours ago Up 3 hours k8s_ghost_pause-test_default_02e7dcb7-5aeb-477f-a50b-74ce1b0a7704_0 cbaab0 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 "/pause" 3 hours ago Up 3 hours k8s_POD_pause-test_default_02e7dcb7-5aeb-477f-a50b-74ce1b0a7704_0

我们创建了一个名为pause-test的pod资源,由busybox、ghost、nginx三个容器组成,其中:

busybox作用是提供Linux基础命令,提供ps、netstat等基础调试命令;

ghost作用是一个博客系统,默认端口2368;

nginx作用是为博客提供反向代理,默认端口80;

以上可模拟构建一套基于共享网络的测试环境。

2.查看pod中容器网络

[root@test-3-217 pause]# kubectl exec -it pause-test -- /bin/sh # 默认进入pod中第一个容器 Defaulting container name to busybox. Use 'kubectl describe pod/pause-test -n default' to see all of the containers in this pod. / # netstat -ntlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:2368 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - / # ps aux PID USER TIME COMMAND 1 root 0:00 sleep 3600 6 root 0:00 /bin/sh 12 root 0:00 ps aux

通过以上输出可以得出:

  • netstat命令我们可以看到nginx和ghost各自的启动端口,因此得出pod中network namespace是可以由不同容器共享的。
  • ps命令我们可以看出pid 为1 的进程是容器自身的ENTRYPOINT进程sleep 3600,而不是/pause。因此得出pod中pid namesapce 没有被容器所共享。

此时我们访问nginx的80端口:

[root@uvmsvr-3-217 pause]# curl 10.244.2.49
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...省略....
</html>

由于默认的nginx镜像没有进行proxy配置,访问的默认页面。由于此时nginx和ghost能够通信,因此我们通过nginx进行代理。

3.nginx代理ghost

# 进入nginx容器
[root@test-3-217 pause]# kubectl exec -it -c nginx pause-test -- /bin/sh
# cd /etc/nginx/conf.d
# 反向代理ghost
# cat > example.conf <<EOF
server {
    listen 80 default_server;
    server_name example.com www.example.com;
    location / {
        proxy_pass http://127.0.0.1:2368;
    }
}
EOF
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# nginx -s reload
2020/06/29 03:25:34 [notice] 15#15: signal process started

# 再次访问nginx
# 注意:由于没有设置service或ingress,只能使用内部ip调试
[root@test-3-217 pause]# curl 10.244.2.49
<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <title>Ghost</title>
    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
....省略....

此时访问nginx不是默认页,而是ghost的页面(由于使用内部ip,暂时无法在浏览器展示),即pod中多个容器是可以共享网络的。

如果上面的例子你已经明白,我们再来看看pause的定义吧。

pause容器定义

Pause容器 全称infrastucture container(又叫infra)基础容器,即它会在每个 Pod 里,额外起一个Infra container 小容器来共享整个 Pod 的 Network Namespace。

Infra container 是一个非常小的镜像,C语言写的、永远处于“暂停”状态的容器。基于Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。

而在网上的大部分文章则用以下解释

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

  • 在pod中担任Linux命名空间共享的基础;
  • 启用pid命名空间,开启init进程;

通过上文的实验pause提供了 network namespace 可以印证第一点“在pod中担任Linux命名空间共享的基础”,但是pid namespace并不是共享的,而是由各自容器ENTRYPOINT自行管理,这是为什么呢?

下面继续通过实例进行讲解。

pause功能演示pid namesapce

1.新建pod资源

apiVersion: v1 kind: Pod metadata: name: pause-test2 spec: # 共享pid namespace shareProcessNamespace: true containers: - name: busybox command: - sleep - "3600" image: busybox imagePullPolicy: IfNotPresent - name: ghost image: ghost:3.21 imagePullPolicy: IfNotPresent - name: nginx image: nginx:1.9.1 imagePullPolicy: IfNotPresent restartPolicy: Always

配置文件中我们新增了shareProcessNamespace: true 可以实现pid namespace在pod中容器共享。

2.进程查看

# 进入新建的pod pause-test2 [root@test-3-217 pause]# kubectl exec -it pause-test2 -- /bin/sh Defaulting container name to busybox. Use 'kubectl describe pod/pause-test2 -n default' to see all of the containers in this pod. / # ps aux PID USER TIME COMMAND 1 root 0:00 /pause 6 root 0:00 sleep 3600 12 1000 0:17 node current/index.js 75 root 0:00 nginx: master process nginx -g daemon off; 80 104 0:00 nginx: worker process 86 root 0:00 /bin/sh 91 root 0:00 ps aux

此时我们可以看到pid 为1的进程是/pause,nginx进程、ghost进程等都可以在busybox容器中看到,即pid namespace在pod中的容器间共享,其好处是便于进程间通信,类似linux操作系统,避免由于容器的异常终止导致僵尸进程。

但是在 Kubernetes 1.8 版本之前,默认是启用 PID namespace 共享的,除非使用 kubelet 标志 –docker-disable-shared-pid=true 禁用。然而在 Kubernetes 1.8 版本以后,情况刚好相反,默认情况下 kubelet 标志 –docker-disable-shared-pid=true,如果要开启,还要设置成 false。也可以给通过pod.spec.shareProcessNamespace 决定是否启用 PID namespace 共享。

至于为什么要关闭pid namespace共享?

因为当应用程序不会产生其他进程,而且僵尸进程带来的问题就可以忽略不计时,就用不到 PID namespace 的共享了。

pause生命周期

# node节点停止pause容器 docker stop 9ebe5f09adfe # 查看pod相关容器 [root@test-3-219 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38be505f017a 94ec7e53edfc "nginx -g 'daemon of…" 23 seconds ago Up 22 seconds k8s_nginx_pause-test2_default_5c98d865-ab34-4ea2-a712-34efb_1 bdd98a7996de dbd2e "docker-entrypoint.s…" 24 seconds ago Up 23 seconds k8s_ghost_pause-test2_default_5c98d865-ab34-4ea2-a712-34efb_1 b2ff89c04fee 1c35c "sleep 3600" 24 seconds ago Up 23 seconds k8s_busybox_pause-test2_default_5c98d865-ab34-4ea2-a712-34efb_1 3d30657ff21e registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 "/pause" 25 seconds ago Up 24 seconds k8s_POD_pause-test2_default_5c98d865-ab34-4ea2-a712-34efb_1 # pod生命周期,没有随pause的停止而停止 [root@test-3-217 pause]# kubectl get pod NAME READY STATUS RESTARTS AGE pause-test 3/3 Running 4 4h54m pause-test2 3/3 Running 3 27m

由于pause容器作为基础容器,在pod内部第一个启动,并且提供namespace级别共享,因此pause生命周期决定了pod内部容器的生命周期。正如上面的实验,pause容器在node节点停止后,kubelet会重新拉起pause容器,此时pod内的容器都会重启,但pod的生命周期并没有随着pause容器的停止而重新计时。

总结

通过pause容器的功能介绍,我们可以更好的了解pod的运行机制以及k8s中namespace是如何进行环境隔离的。

文章参考:

https://www.bbsmax.com/A/VGzlQYmYJb/

https://www.ianlewis.org/en/almighty-pause-container

https://cloud.tencent.com/developer/article/

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/52230.html

(0)

相关推荐

发表回复

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

关注微信