启动进程命名空间共享机制,只需要在 Pod 定义中设置shareProcessNamespace=true
即可完成。通过下面例子展示一个 Pod 中两个容器共享进程命名空间的效果,share-process-namespace.yaml 配置文件的内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
securityContext:
capabilities:
add:
- SYS_PTRACE
stdin: true
tty: true
其中,主容器为一个 nginx 提供的服务,另一个容器为 busybox 提供的查错工具,被命名为“shell”。在 shell 的容器的 securityContext.capabilities 中增加了 CAP_SYS_PTRACE 能力,用于提供进程跟踪操作能力。
使用 kubectl create
命令创建这个Pod:
[root@master1 ~]# kubectl create -f share-process-namespace.yaml
pod/nginx created
查看 Pod 中 container:
[root@master1 ~]# kubectl get pods nginx -o jsonpath={.spec.containers[*].name}
nginx shell
进入 shell 的容器环境中,使用ps
命令可以查看到 nginx 和自身容器的全部进程:
[root@master1 ~]# kubectl exec -it nginx -c shell -- sh
/ # ps -elf
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
35 101 0:00 nginx: worker process
36 101 0:00 nginx: worker process
37 root 0:00 sh
42 root 0:00 sh
47 root 0:00 ps -elf
/ #
由于 shell 容器具备 CAP_SYS_PTRACE 能力,所以它还可以对其他进程发送操作系统信号,例如对 nginx 的 6 号进程发出 SIGHUP 信号用于重启 nginx 程序:
/ # kill -SIGHUP 6
/ # ps -elf
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
37 root 0:00 sh
42 root 0:00 sh
48 101 0:00 nginx: worker process
49 101 0:00 nginx: worker process
50 root 0:00 ps -elf
/ #
nginx 的原 worker 进程(PID 为35、36)重启后启动了一个新的 PID 为 48、49 的 worker 进程。
有两个容器共享进程命名空间的 Pod 环境有以下特性:
- 各容器的进程 ID(PID)混合在一个环境中,都不再拥有进程号 PID=1 的启动进程,1 号进程由 Pod 的 Pause 容器使用。对于某些必须以进程号1作为启动程序 PID 的容器来说,将会无法启动,例如以 systemd 作为启动命令的容器。
- 进程信息在多个容器间相互可见,这包括 /proc 目录下的所有信息,其中可能有包含密码类敏感信息的环境变量,只能通过 UNIX 文件权限进行访问控制,需要设置容器内的运行用户或组。
- 一个容器的文件系统存在于 /proc/$pid/root 目录下,所以不同的容器也能访问其他容器的文件系统的内容,这对于 debug 查错来说非常有用,但也意味着没有容器级别的安全隔离,只能通过 UNIX 文件权限进行访问控制,需要设置容器内的运行用户或组。
例如,在shell容器内可以查看到nginx容器的配置文件的内容:
/ # cat /proc/6/root/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
/ #
参考:《Kubernetes权威指南(第五版)》