启动进程命名空间共享机制,只需要在 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权威指南(第五版)》