Search code examples
kuberneteskubernetes-podkubernetes-deploymentkubernetes-dashboardworkload

How do i directly know the root parent workload that a Pod belongs to


Problem Statement:

I have a Pod which belongs to a workload, now I want to know the workload that initiated that Pod. One way of doing it right now is going through the ownerReference and then going up the chain recursively finding for the root parent workload that initiated the pod.

Is there a way I can directly know which root parent workload initiated the Pod?


Solution

  • First, please remember that pods created by specific workload have this workload's name in the pod name. For example, pods defined in deployments have following pod naming convention:

    <replicaset-name>-<some-string>

    and replica set name is:

    <deployment-name>-<some-string>

    So for example:

    Pod name: nginx-66b6c48dd5-84rml Replica set name: nginx-66b6c48dd5 Deployment name: nginx

    So the first part of the name which doesn't seem to be some random letters / number is the root workload name.

    Only pods defined in StatefulSet have ordinal indexes, as follows:

    <statefulset-name>-<ordinal index>

    For example:

    Pod name: web-0 StafeulSet name: web

    Of course, based on workload name we are not able to know what kind of workload it is. Check the second part of my answer below.


    Well, not taking into account the pod's name, it seems that your thinking is correct, the only way to find a "root" workload is to go through the chain recursively and find the next "parents" workloads.

    When you run the command kubectl get pod {pod-name} -o json (to get all information about pod) there is only information about above level (as you said in case of pod defined in deployment, in pod information there is only information about replica set).

    I wrote a small bash script that recursively checks every workload's ownerReferences until it finds "root" workload (the root workload does not have ownerRefernces). It requires you to have jq utility installed on your system. Check this:

    #!/bin/bash
    
    function get_root_owner_reference {
        # Set kind, name and namespace
        kind=$1
        name=$2
        namespace=$3
    
        # Get ownerReferences
        owner_references=$(kubectl get $kind $name -o json -n $namespace | jq -r 'try (.metadata.ownerReferences[])')
    
        # If ownerReferences does not exists assume that it is root workload; if exists run get_root_owner_reference function
        if [[ -z "$owner_references" ]]; then
            resource_json=$(kubectl get $kind $name -o json -n $namespace)
            echo "Kind: $(echo $resource_json | jq -r '.kind')"
            echo "Name: $(echo $resource_json | jq -r '.metadata.name')"
        else
            get_root_owner_reference $(echo $owner_references | jq -r '.kind') $(echo $owner_references | jq -r '.name') $namespace
        fi
    
    }
    
    # Get namespace if set
    if [[ -z $3 ]]; then
        namespace="default"
    else
        namespace=$3
    fi
    
    get_root_owner_reference $1 $2 $namespace
    

    You need to provide two arguments - resource and name of the resource. Namespace name is optional (if not given it will use Kubernetes default namespace).

    Examples: Pod defined in deployment:

    user@cloudshell:~/ownerRefernce$ ./get_root_owner_reference.sh pod nginx-66b6c48dd5-84rml
    Kind: Deployment
    Name: nginx
    

    Pod created from CronJob:

    user@cloudshell:~/ownerRefernce$ ./get_root_owner_reference.sh pod hello-27247072-mv4l9
    Kind: CronJob
    Name: hello
    

    Pod created straight from pod definition:

    user@cloudshell:~/ownerRefernce$ ./get_root_owner_reference.sh pod hostipc-exec-pod
    Kind: Pod
    Name: hostipc-exec-pod
    

    Pod from other namespace:

    user@cloudshell:~/ownerRefernce$ ./get_root_owner_reference.sh pod kube-dns-679799b55c-7pzr7 kube-system
    Kind: Deployment
    Name: kube-dns