前言¶
前面我们通过 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