首页 > 解决方案 > 使用 containerd 为容器创建同级进程

问题描述

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

在检查主节点进程(ps -aef --forest)时,我可以看到containerd-shim运行 weave 插件的进程在它的树中有 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-utilspid 31199)发出的进程(pid 31656)如何是它的兄弟进程而不是子进程?launch.sh

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

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

在我的情况下,与 weavelaunch.sh的想法相似:

#!/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

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

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

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

谢谢你们。

标签: linuxdockerkubernetesweavecontainerd

解决方案


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

我复制了您的设置并遇到了类似的情况(其中一个sleep命令不是 的兄弟launch.sh)。为此,您需要在您的DeploymentPodYAML 中使用以下参数:

  • 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

PodYAML 定义:

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"]

PodYAML 定义:

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

应用此资源的清单后(使用构建的图像或使用 a ConfigMap),您应该能够运行(在运行 this 的节点上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

推荐阅读