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 1
的 init 进程
有它维护,并接收收割僵尸进程
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