Pause Pod 介绍

发布时间: 更新时间: 总字数:1076 阅读时间:3m 作者: IP上海 分享 网址

Pause 容器就是为解决 Pod 中的网络问题而生的

说明

  • 名称:pause container or Infra container
  • 代码:https://github.com/kubernetes/kubernetes/tree/master/build/pause
  • 镜像:gcmirrors/pause-amd64:3.2 / gcr.io/google_containers/pause-amd64:3.2

作用

kubernetes 中的 pause容器 主要作用:

特点

  • 镜像非常小,300KB左右
  • 永远处于Pause(暂停)状态

示例

启动 pause 容器

$ docker run -d --ipc=shareable --name pause -p 8080:80 gcmirrors/pause-amd64:3.2
51119a130c6b0e6fd7d575e5afc3e107afdc0e7a293aefb43218998e3847dfc1
$ docker ps | grep pause
51119a130c6b   gcmirrors/pause-amd64:3.2   "/pause"   5 seconds ago   Up 5 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   pause

pause 容器 初始化 network/pid/ipc namespace,共后边的容器加入

启动 nginx 容器

$ cat <<EOF >> nginx.conf
error_log stderr;
events { worker_connections  1024; }
http {
    access_log /dev/stdout combined;
    server {
        listen 80 default_server;
        server_name example.com www.example.com;
        location / {
            proxy_pass http://127.0.0.1:2368;
        }
    }
}
EOF

$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx
41cbf6f0a737efaed085d37543c5774fb75ef51ceed34a377274265a9bdcbb57
  • nginx 容器 代理本地的 2368 端口
  • 这种加入 pause 容器 并加入其他容器的方式也是 Kubernetes 启动 Pod 的原理

启动 ghost 容器

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

ghost 容器 暴露 2368 端口

验证

$ docker ps
CONTAINER ID   IMAGE                       COMMAND                  CREATED          STATUS          PORTS                                   NAMES
3463919cbb75   ghost                       "docker-entrypoint.s…"   59 seconds ago   Up 57 seconds                                           ghost
41cbf6f0a737   nginx                       "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes                                            nginx
51119a130c6b   gcmirrors/pause-amd64:3.2   "/pause"                 3 minutes ago    Up 3 minutes    0.0.0.0:8080->80/tcp, :::8080->80/tcp   pause

nginx 访问

只有 pause 容器 有端口映射到导宿主机 8080 端口,访问:

$ curl -v http://127.0.0.1:8080
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.21.5
< Content-Type: text/html; charset=utf-8
< Content-Length: 24091
< Connection: keep-alive
< X-Powered-By: Express
< Cache-Control: public, max-age=0
< ETag: W/"5e1b-4nYwijbk8T8+zHoFzwTedcChdZg"
< Vary: Accept-Encoding
...

进程验证

$ docker exec -it ghost ls /proc/
1
183
39
40
7
$ docker exec -it ghost cat /proc/1/cmdline  # pause 主进程
/pause
$ docker exec -it ghost cat /proc/7/cmdline  # nginx 主进程
nginx: master process nginx -g daemon off;
$ docker exec -it ghost cat /proc/39/cmdline  # nginx worker 进程
nginx: worker process
$ docker exec -it ghost cat /proc/40/cmdline  # ghost 进程
nodecurrent/index.js

结论

  • pause 容器 将器内部的 80 端口通过 iptable 映射到宿主机的 8080 端口
  • nginx 容器 通过指定 –net/ipc/pid=container:pause 绑定到 pause 容器的 net/ipc/pid namespace
  • ghost 容器 通过指定 –net/ipc/pid=container:pause 绑定到 pause 容器的 net/ipc/pid namespace
  • 三个容器共享 net namespace,可以使用localhost直接通信

扩展

  • k8s 中 pause 容器 是所有容器的 父容器(parent container),它有2个作用
    • 它是pod中 Linux命名空间 共享的基础
    • 启用 PID 命名空间 共享,pod 中 PID 1init 进程有它维护,并接收收割僵尸进程
  • kubelet 通过配置 --docker-disable-shared-pid=false 开启共享 pid namespace,也可以在 yml 中指定
cat << EOF >> test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  selector:
    matchLabels:
      app: pod1
  replicas: 1
  template:
    metadata:
      labels:
        app: pod1
    spec:
      shareProcessNamespace: true
      containers:
      - name: sshd
        image: circleci/sshd:0.1
        env:
        - name: PUBKEY
          value: "abc"
      - name: pod1
        image: busybox
        securityContext:
          capabilities:
            add:
            - SYS_PTRACE
        stdin: true
        tty: true
        ports:
        - name: p80
          containerPort: 80
        - name: p22
          containerPort: 22
EOF

FaQ

  • 错误日志
$ docker run ...
docker: Error response from daemon: can't join IPC of container 9c29bd28c89b09f1cc24de524dd9883482254bb8b0c530d06a588056a72797ec: non-shareable IPC (hint: use IpcMode:shareable for the donor container).
  • 解决方法一

修改 /etc/docker/daemon.json 如下:

{
  "default-ipc-mode": "shareable"
}

重启 docker

systemctl restart docker
  • 解决方法二

启动 pause 容器 指定 docker run ... --ipc=shareable

参考

  1. https://www.ianlewis.org/en/almighty-pause-container
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数