How to retrieve the pod/container in which run a given process

2/1/2022

Using crictl ancontainerd, is there an easy way to find to which pod/container belongs a given process, using it'sPID` on the host machine?

For example, how can I retrieve the name of the pod which runs the process below (1747):

root@k8s-worker-node:/# ps -ef | grep mysql
1000        1747    1723  0 08:58 ?        00:00:01 mysqld
-- Fabrice Jammes
containerd
kubernetes
kubernetes-pod

2 Answers

2/2/2022

1. Using pid2pod

pid2pod is a dedicated tool: https://github.com/k8s-school/pid2pod

Example:

# Install
$ curl -Lo ./pid2pod https://github.com/k8s-school/pid2pod/releases/download/v0.0.1/pid2pod-linux-amd64 
$ chmod +x ./pid2pod
$ mv ./pid2pod /some-dir-in-your-PATH/pid2pod

# Run
$ ./pid2pod 1525
NAMESPACE     POD                 CONTAINER     PRIMARY PID
kube-system   calico-node-6kt29   calico-node   1284

2. Using sysdig OSS

Install sysdig and run:

sudo csysdig -pc

You'll get something in the htop's style: enter image description here

3. Custom script

Using @Iarsks answer, I propose a solution based on command belown which provides the pod name for a given PID:

$ pid=1254
$ nsenter -t $pid -u hostname
coredns-558bd4d5db-rxz9r

This solution display namespace, pod, container and container's primary PID. It is possible to copy paste the script below in a file named get_pid.sh and then run ./get_pid.sh 2345 for example.

#!/bin/bash

# Display pod information about a process, using its host PID as input

set -euo pipefail

usage() {
  cat << EOD

Usage: `basename $0` PID

  Available options:
    -h          this message

Display pod information about a process, using its host PID as input:
- display namespace, pod, container, and primary process pid for this container if the process is running in a pod
- else exit with code 1
EOD
}

if [ $# -ne 1 ] ; then
    usage
    exit 2
fi

pid=$1
is_running_in_pod=false

pod=$(nsenter -t $pid -u hostname 2>&1)
if [ $? -ne 0 ]
then
    printf "%s %s:\n %s" "nsenter command failed for pid" "$pid" "$pod"
fi

cids=$(crictl ps -q)
for cid in $cids
do
  current_pod=$(crictl inspect -o go-template --template '{{ index .info.config.labels "io.kubernetes.pod.name"}}' "$cid")
  if [ "$pod" == "$current_pod" ]
  then
    tmpl='NS:{{ index .info.config.labels "io.kubernetes.pod.namespace"}} POD:{{ index .info.config.labels "io.kubernetes.pod.name"}} CONTAINER:{{ index .info.config.labels "io.kubernetes.container.name"}} PRIMARY PID:{{.info.pid}}'
	crictl inspect --output go-template --template "$tmpl" "$cid"
    is_running_in_pod=true
    break
  fi
done

if [ "$is_running_in_pod" = false ]
then
  echo "Process $pid is not running in a pod."
  exit 1
fi

WARNING: this solution does not work if two pods have the same name (even in different namespaces)

-- Fabrice Jammes
Source: StackOverflow

2/2/2022

Assuming that you're looking at the primary process in a pod, you could do something like this:

crictl ps -q | while read cid; do
    if crictl inspect -o go-template --template '{{ .info.pid }}' $cid | grep -q $target_pid; then
        echo $cid
    fi
done

This walks through all the crictl managed pods and checks the pod pid against the value of the $target_pid value (which you have set beforehand to the host pid in which you are interested).

-- larsks
Source: StackOverflow