根据进程信息获取对应进程所属的容器/Pod 信息(一)

前言

前面我们通过 ebpf 程序获取到了执行操作的对应进程的进程信息,一般来说还会有需要获取这个进程所属的容器或 Pod 信息的需求。 本文记录一下一种获取进程所属的容器信息的方法(知道了容器信息通过其他方法可以很容易的找到容器所属的 Pod 信息)。

通过 /proc/<pid>/cgroup 文件获取容器信息

如标题所述,我们可以通过读取 /proc/<pid>/cgroup 文件来获取进程所属的容器 id,通过容器 id 自然就可以找到对应的容器了。

这个 cgroup 文件的内容示例如下:

0::/kubepods/besteffort/pod779e55c6-0467-4431-997f-25a71a8e8a8e/a9ccdd00512985cb6e6c8dff176cb3086a989e477200c9a1cfdf8749182fc1da

其中, a9ccdd00512985cb6e6c8dff176cb3086a989e477200c9a1cfdf8749182fc1da 就是我们要找的容器 id。

下面通过一个示例来验证一下这个方法。 这个示例程序将监控 execve 系统调用,并且只记录进程名称是 sh 的事件, 在输出事件时,将在 go 程序中通过读取 /proc/<pid>/cgroup 文件的内容获取对应的容器 id 信息。

示例的源代码可以通过 https://github.com/mozillazg/hello-libbpfgo/tree/master/06-get-container-info-1 获取。

编译并运行程序:

$ make
$ sudo ./main

在另一个窗口中通过 kubectl 创建一个使用 sh 命令执行操作的 pod:

$ kubectl run test --image docker.io/calico/node:v3.19.1 \
    -- sh -c 'while true; do ls > /dev/null && sleep 10; done'
pod/test created

$ kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
test   1/1     Running   0          3s

当 pod Running 后,可以在前面执行 sudo ./main 的窗口中看到类似如下的输出:

..., Comm: sh, ContainerId: f1abcafee046eda0e9d78691dcc20fcde1d008bb84a2b08dedfbd2cd4d8feb99

通过 kubectl 查看创建的 pod 信息可以看到这个容器 id 就是这个 pod 的容器对应的id:

$ kubectl describe pod test |grep f1abcafee046eda0e9d78691dcc20fcde1d008bb84a2b08dedfbd2cd4d8feb99 -A 8
    Container ID:  containerd://f1abcafee046eda0e9d78691dcc20fcde1d008bb84a2b08dedfbd2cd4d8feb99
    Image:         docker.io/calico/node:v3.19.1
    Image ID:      docker.io/calico/node@sha256:bc4a631d553b38fdc169ea4cb8027fa894a656e80d68d513359a4b9d46836b55
    Port:          <none>
    Host Port:     <none>
    Args:
      sh
      -c
      while true; do ls > /dev/null && sleep 10; done

Comments