使用 containerd 为容器创建兄弟进程

Creating a sibling process to a container using containerd

我有一个 Kubernetes 集群(Docker 和 containerd),我在其中部署了 Weave CNI plugin

检查主节点进程 (ps -aef --forest) 时,我可以看到运行 weave 插件的 containerd-shim 进程在它的树中有 3 个进程:

31175  16241 \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/836489.. -address /run/containerd/contai
31199  31175 |   \_ /bin/sh /home/weave/launch.sh
31424  31199 |   |   \_ /home/weave/weaver --port=6783 --datapath=datapath --name=36:e4:33:8
31656  31175 |   \_ /home/weave/kube-utils -run-reclaim-daemon -node-name=ubuntu -peer-name=36:e4

我无法理解的是 kube-utils 进程 (pid 31656) 是如何从 launch.sh 脚本进程 (pid 31199) 发出的它而不是子进程?

我试图创建一个类似的环境来模拟这种情况,方法是从以下内容创建一个 docker 图像:

FROM ubuntu:18.04
ADD ./launch.sh /home/temp/
ENTRYPOINT ["/home/temp/launch.sh"]

在我的案例中,launch.sh 的想法与 that of weave 相似:

#!/bin/sh

start() {
    sleep 2000&
}

start &

sleep 4000

将其部署到集群后,我得到以下进程树:

114944  16241 \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/d9a6904 -address /run/containerd/contai
114972 114944     \_ /bin/sh /home/temp/launch.sh
115002 114972         \_ sleep 4000
115003 114972         \_ sleep 2000

而且您可以看到这两个进程都是主容器进程的子进程,而不是兄弟进程。

根据上面的 weave 场景,我希望 sleep 2000 进程是 launch.sh 进程的兄弟进程,而不是子进程。

知道如何解释上面的编织情况吗?我怎样才能在本地复制这个?或者在什么情况下为容器进程创建兄弟进程?

谢谢大家

According to the weave scenario above, I would expect that the sleep 2000 process would be a sibling to the launch.sh process and not a child.

我重现了您的设置并遇到了类似的情况(其中一个 sleep 命令不是 launch.sh 的同级命令)。为此,您需要在 DeploymentPod YAML 中使用以下参数:

  • hostPid
  • securityContext: 
      privileged: true
    

您可以在此处阅读有关 hostPid 的更多信息:

您可以在此处阅读有关 securityContext 的更多信息:


它与 Weave 一起工作,因为它具有上述参数。您可以在这里查看它们:

此外,此过程 运行 由:


例子

此示例展示了如何进行设置,其中 sleep 命令将成为 launch.sh 的同级命令。

过程可能不同:

  • 使用 ConfigMap 和脚本作为入口点
  • 构建包含所有文件的映像

launch.sh 文件:

#!/bin/bash
start() {
    sleep 10030 &
}
start &
( sleep 10040 &)
sleep 10050 &
/bin/sh -c 'sleep 10060'

使用 ConfigMap 和脚本作为入口点

您可以使用上面的脚本创建一个 configMap,它将用于 运行 一个 pod:

  • $ kubectl create cm --from-file=launch.sh

Pod YAML 定义:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: bashtest
  name: bashtest
spec:
  containers:
  - image: ubuntu
    name: bashtest
    command: ["/mnt/launch.sh"]
    resources: {}
    securityContext:
       privileged: true
    volumeMounts:
    - mountPath: /mnt/launch.sh
      name: ep
      subPath: launch.sh
  dnsPolicy: ClusterFirst
  restartPolicy: Always
  hostPID: true
  volumes:
    - name: ep
      configMap:
        defaultMode: 0750
        items:
        - key: launch.sh
          path: launch.sh
        name: entrypoint

构建包含所有文件的映像

您还可以构建图像。请记住,此图片仅用于 示例目的

Dockerfile:

FROM ubuntu:18.04
ADD ./launch.sh /
RUN chmod 777 ./launch.sh
ENTRYPOINT ["/launch.sh"]

Pod YAML 定义:

apiVersion: v1
kind: Pod
metadata:
  name: process
  labels:
    app: ubuntu
spec:
  containers:
  - image: gcr.io/dkruk-test-00/bashtest
    imagePullPolicy: Always
    name: ubuntu
    securityContext:
       privileged: true
  hostPID: true
  restartPolicy: Always

在为此资源应用清单后(使用内置映像或使用 ConfigMap),您应该能够 运行(在 运行 宁此的节点上Pod):

  • $ ps -aef --forest

并看到类似于此的输出(仅部分):

root     2297272     290  0 09:44 ?        00:00:00  \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/5c802039033683464d5a586
root     2297289 2297272  0 09:44 ?        00:00:00      \_ /bin/bash /launch.sh
root     2297306 2297289  0 09:44 ?        00:00:00      |   \_ sleep 10050
root     2297307 2297289  0 09:44 ?        00:00:00      |   \_ /bin/sh -c sleep 10060
root     2297310 2297307  0 09:44 ?        00:00:00      |       \_ sleep 10060
root     2297305 2297272  0 09:44 ?        00:00:00      \_ sleep 10040
root     2297308 2297272  0 09:44 ?        00:00:00      \_ sleep 10030