Получить pid пода в kubernetes

При работе с kubernetes иногда возникает необходимость найти pid процесса в поде контейнере. Например, посмотреть в реальном времени нагрузку через pidstat, или снять tcpdump с контейнера. Просто получить pid процесса в контейнере через kubectl не получается.

Способ 1

$ kubectl get -o json po calico-node-vg5mh | jq -r '.metadata.uid'
2622bcf3-ee02-4bec-8987-d5e0c4f0683a
$ kubectl get -o json po calico-node-vg5mh -o jsonpath='{.metadata.uid}'
2622bcf3-ee02-4bec-8987-d5e0c4f0683a

Дальше получаем ноду, на которой крутится под

$ kubectl get -o json po calico-node-vg5mh | jq -r '.spec.nodeName'
kube1

или

kubectl get po -o wide calico-node-vg5mh
NAME                READY   STATUS    RESTARTS   AGE   IP           NODE                  NOMINATED NODE   READINESS GATES
calico-node-vg5mh   1/1     Running   1          23h   10.47.9.52   kube1                 <none>           <none>

Нам потребуется заменить дефисы на звёздочки, т.к. в cgroups driver systemd uid разделяется подчёркиваниями, а не дефисами

$ echo "2622bcf3-ee02-4bec-8987-d5e0c4f0683a" | tr '-' '*'
2622bcf3*ee02*4bec*8987*d5e0c4f0683a

Теперь заходим на нужную ноду и ищем процессы для этого uid. Пути cgroups будут отличаться

cgroupfs:


root@kube1:~# head /sys/fs/cgroup/cpu/**/*/*2622bcf3*ee02*4bec*8987*d5e0c4f0683a*/*/cgroup.procs
==> /sys/fs/cgroup/cpu/kubepods/burstable/pod2622bcf3-ee02-4bec-8987-d5e0c4f0683a/1b4a9fa81b44aec60a68004c5bcc34c257a4565389d468431cc0c60da74e0670/cgroup.procs <==
3268547

==> /sys/fs/cgroup/cpu/kubepods/burstable/pod2622bcf3-ee02-4bec-8987-d5e0c4f0683a/c590095fc0cf1348430ca6e31e83f8c6a6881e2f8874e7f2b2c4223c55d53c63/cgroup.procs <==
3269137
3269211
3269212
3269213
3269214
3269215
3269350
3269351
3454053
3454113

systemd:

root@kube1:~# head /sys/fs/cgroup/cpu/**/*/*pod0fab7fef*8df4*4f58*a59c*342c81488230*/*/cgroup.procs
==> /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod0fab7fef_8df4_4f58_a59c_342c81488230.slice/cri-containerd-8cd9a38188994e8e1ba6c3e26534e8d5ae3474e990420ffd05007e59867362eb.scope/cgroup.procs <==
171153
171269
171270
171271
171272
171273
171408
171409
331845
331855

==> /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod0fab7fef_8df4_4f58_a59c_342c81488230.slice/cri-containerd-f8cfce689b0076e7e4a047e71ba53cea9944c40173c7490f471855a792d26dec.scope/cgroup.procs <==
170735

Способ 2: docker

root@kube1:~# docker ps | grep calico-node
c590095fc0cf   1470783b1474           "start_runit"            23 hours ago   Up 23 hours             k8s_calico-node_calico-node-vg5mh_kube-system_2622bcf3-ee02-4bec-8987-d5e0c4f0683a_1
1b4a9fa81b44   k8s.gcr.io/pause:3.2   "/pause"                 23 hours ago   Up 23 hours             k8s_POD_calico-node-vg5mh_kube-system_2622bcf3-ee02-4bec-8987-d5e0c4f0683a_0

Вызываем docker top для конкретного контейнера

root@kube1:~# docker top c590095fc0cf
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                3269137             3269118             0                   Mar18               ?                   00:00:00            /usr/local/bin/runsvdir -P /etc/service/enabled
root                3269211             3269137             0                   Mar18               ?                   00:00:00            runsv bird
root                3269212             3269137             0                   Mar18               ?                   00:00:01            runsv confd
root                3269213             3269137             0                   Mar18               ?                   00:00:00            runsv felix
root                3269214             3269137             0                   Mar18               ?                   00:00:01            runsv allocate-tunnel-addrs
root                3269215             3269137             0                   Mar18               ?                   00:00:00            runsv bird6
root                3269350             3269215             0                   Mar18               ?                   00:00:08            bird6 -R -s /var/run/calico/bird6.ctl -d -c /etc/calico/confd/config/bird6.cfg
root                3269351             3269211             0                   Mar18               ?                   00:00:09            bird -R -s /var/run/calico/bird.ctl -d -c /etc/calico/confd/config/bird.cfg
root                3454053             3269212             0                   Mar18               ?                   00:00:08            calico-node -confd
root                3454113             3269214             0                   Mar18               ?                   00:00:07            calico-node -allocate-tunnel-addrs
root                3454125             3269213             1                   Mar18               ?                   00:15:11            calico-node -felix

Способ 3: containerd

Находим контейнер через crictl через grep

root@kube1:~# crictl pods | grep calico-node
f8cfce689b007       23 hours ago        Ready               calico-node-ldkpk                             kube-system         0                   (default)

или по uid:

$ kubectl get -o json po calico-node-ldkpk | jq -r '.metadata.uid'
0fab7fef-8df4-4f58-a59c-342c81488230
$ kubectl get -o json po calico-node-ldkpk -o jsonpath='{.metadata.uid}'
0fab7fef-8df4-4f58-a59c-342c81488230

И фильтруем по uid

root@kube1:~# crictl pods --label 'io.kubernetes.pod.uid=0fab7fef-8df4-4f58-a59c-342c81488230'
POD ID              CREATED             STATE               NAME                NAMESPACE           ATTEMPT             RUNTIME
f8cfce689b007       24 hours ago        Ready               calico-node-ldkpk   kube-system         0                   (default)

Теперь по pod id можем найти основной pid

root@kube2:~# crictl inspectp f8cfce689b007 | jq '.info.pid'
170735

И даже применить однострочник:

root@kube2:~# crictl inspectp $(crictl pods --label 'io.kubernetes.pod.uid=0fab7fef-8df4-4f58-a59c-342c81488230' -q) | jq '.info.pid'
170735