路漫漫其修远兮
吾将上下而求索

k8s学习:根据 PID 获取容器所在的 Pod 名称

在管理 Kubernetes 集群的过程中,我们经常会遇到这样一种情况:在某台节点上发现某个进程资源占用量很高,却又不知道是哪个容器里的进程。有没有办法可以根据 PID 快速找到 Pod 名称呢?

假设现在有一个 java 的pid  41406,内存高,要定位

image.png

为了进一步挖掘信息,有两种思路,一种是挖掘 PID 对应的容器的信息,另一种是挖掘 PID 对应的 Pod 的信息。

获取信息Container ID

要获取容器的 ID,可以查看 PID 对应的 cgroup 信息:

cat /proc/41406/cgroup
11:memory:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
10:devices:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
9:cpuset:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
8:blkio:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
7:perf_event:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
6:net_cls,net_prio:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
5:pids:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
4:hugetlb:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
3:cpu,cpuacct:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
2:freezer:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d
1:name=systemd:/kubepods/burstable/pod4e418566-c641-11ea-83ed-e4434b6414b0/96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d

可以看到该进程对应的容器 ID 为 96b326e8…,可以再优化一下上面的命令,直接获取容器 ID:

cat /proc/41406/cgroup | awk -F '/' '{print $5}' | head -n 1  
96b326e83e391de8aaa2b4440905a67f991db658c0465e2d4951698882b5212d

最后一步根据容器 ID 获取 Pod 名称,如果你的容器运行时是 containerd 或 crio,可以使用 crictl 来获取容器信息:

命令下载:https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.22.0/crictl-v1.22.0-linux-amd64.tar.gz

# Go Template
$ crictl inspect -o go-template --template='{{index .status.labels "io.kubernetes.pod.name"}}' 96b326e8
zo-mbs-deployment-6d9d84cfb-zh58l

# jq
$ crictl inspect 96b326e8|jq '.status.labels["io.kubernetes.pod.name"]'
zo-mbs-deployment-6d9d84cfb-zh58l

使用 Go template 或 jq 都能获取 Pod 名称,看个人喜好。

如果你的容器运行时是 Docker,可以使用命令行工具 docker 来获取,方法和上面类似。

整合

方法是有了,怎么才能将所有的步骤合并成一个步骤,一步到位获取 Pod 名称呢?可以在 ~/.bashrc 中添加一个 shell 函数,选择上面的方法 1,并使用 go template 来格式化(你也可以使用上面提到的其他方法,但需要安装 jq):

cat << EOF | sudo tee /usr/local/bin/podinfo > /dev/null
cid=\$(cat /proc/\$1/cgroup | awk -F '/' '{print \$5}' | awk -F '-' '{print \$3}' | head -n 1)
cid=\$(echo \${cid:0:8})
namespace=\$(crictl inspect -o go-template --template='{{index .status.labels "io.kubernetes.pod.namespace"}}' \$cid)
name=\$(crictl inspect -o go-template --template='{{index .status.labels "io.kubernetes.pod.name"}}' \$cid)
echo "namespace: \$namespace podname: \$name"
EOF

sudo chmod +x /usr/local/bin/podinfo

执行
podinfo 41406
namespace: crm-daily podname: zo-mbs-deployment-6d9d84cfb-zh58l

未经允许不得转载:江哥架构师笔记 » k8s学习:根据 PID 获取容器所在的 Pod 名称

分享到:更多 ()

评论 抢沙发

评论前必须登录!