kubernetescontainerd

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


Using crictl in containerd, is there an easy way to find to which pod/container belongs a given process, using its PID 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

Solution

  • 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)