前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k8s中 pause 容器作用

k8s中 pause 容器作用

原创
作者头像
iginkgo18
发布2023-07-21 16:41:13
6691
发布2023-07-21 16:41:13
举报
文章被收录于专栏:devops_k8sdevops_k8s

1 现象

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

例如:

代码语言:javascript
复制
# 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
0969c5802814        1c35c4412082                                                               "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中的多个容器共享同一个network namespace,因此这些容器可以共享pod的IP和端口。

其中共享的network namespace就是通过pause容器实现的。

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

2 pause功能演示 network namespace

2.1 创建 pod 资源

代码语言:javascript
复制
# 配置文件
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        1c35c4412082                                                               "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        db9598608d2e                                                               "docker-entrypoint.s…"   3 hours ago         Up 3 hours                                      k8s_ghost_pause-test_default_02e7dcb7-5aeb-477f-a50b-74ce1b0a7704_0
cbaab0586322        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.2 查看 pod 中容器网络

代码语言:javascript
复制
[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端口:

代码语言:javascript
复制
[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进行代理。

2.3 nginx代理ghost

代码语言:javascript
复制
# 进入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的定义吧。

3 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自行管理,这是为什么呢?

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

4 pause功能演示pid namespace

4.1 新建 pod 资源

代码语言:javascript
复制
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中容器共享。

4.2 进程查看

代码语言:javascript
复制
# 进入新建的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 的共享了。

5 pause生命周期

代码语言:javascript
复制
# 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-34ef5431864b_1
bdd98a7996de        db9598608d2e                                                               "docker-entrypoint.s…"   24 seconds ago      Up 23 seconds                                     k8s_ghost_pause-test2_default_5c98d865-ab34-4ea2-a712-34ef5431864b_1
b2ff89c04fee        1c35c4412082                                                               "sleep 3600"             24 seconds ago      Up 23 seconds                                     k8s_busybox_pause-test2_default_5c98d865-ab34-4ea2-a712-34ef5431864b_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-34ef5431864b_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容器的停止而重新计时。

文章参考:

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

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

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

原创: 三页 木纳大叔爱运维

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 现象
  • 2 pause功能演示 network namespace
    • 2.1 创建 pod 资源
      • 2.2 查看 pod 中容器网络
        • 2.3 nginx代理ghost
        • 3 pause容器定义
        • 4 pause功能演示pid namespace
          • 4.1 新建 pod 资源
            • 4.2 进程查看
            • 5 pause生命周期
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档