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?
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