Wednesday, December 8, 2021

Locate Origin of Kubernetes Pods using Go

 


In this post we will find for each running pod, the source deployment or statefulset that caused it to run. This is required if we want to show this information in a nice table, or or we want to get additional information about the pod from the source deployment or statefulset.


We start by initiating the kubernetes client. See this post for information about methods to create the kubernetes client.



package main

import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"os"
"path/filepath"
)

func main() {
configPath := filepath.Join(os.Getenv("HOME"), ".kube", "config")
restConfig, err := clientcmd.BuildConfigFromFlags("", configPath)
if err != nil {
panic(err)
}

k8sClient, err := kubernetes.NewForConfig(restConfig)
if err != nil {
panic(err)
}



Next we want to fill up a map of owners. This is a map of statefulsets and deployments that caused a pod to start. Notice that deployments are actually starting a replicaset, so we add the replicaset name to point to the original deployment.



owners := make(map[string]string)

listOptions := metav1.ListOptions{}
namespace := "default"

statefulsets, err := k8sClient.AppsV1().StatefulSets(namespace).List(context.Background(), listOptions)
if err != nil {
panic(err)
}
for _, statefulSet := range statefulsets.Items {
owners[statefulSet.Name] = fmt.Sprintf("statefulset %v", statefulSet.Name)
}

deployments, err := k8sClient.AppsV1().Deployments(namespace).List(context.Background(), listOptions)
if err != nil {
panic(err)
}

for _, deployment := range deployments.Items {
owners[deployment.Name] = fmt.Sprintf("deployment %v", deployment.Name)
}

replicasets, err := k8sClient.AppsV1().ReplicaSets(namespace).List(context.Background(), listOptions)
if err != nil {
panic(err)
}

for _, replica := range replicasets.Items {
for _, owner := range replica.OwnerReferences {
deployment := owners[owner.Name]
owners[replica.Name] = deployment
}
}



Having the owners map populated, we can now scan the pods, and print the owner for each pod.



pods, err := k8sClient.CoreV1().Pods(namespace).List(context.Background(), listOptions)
if err != nil {
panic(err)
}

for _, pod := range pods.Items {
for _, owner := range pod.OwnerReferences {
parent := owners[owner.Name]
fmt.Printf("pod %v owner %v\n", pod.Name, parent)
}
}



And an example output is:



pod sample-hackazon-deployment-546f47b8cb-j4j7x owner deployment sample-hackazon-deployment

pod sample-hackazon-mysql-deployment-bd6465f75-m4sgc owner deployment sample-hackazon-mysql-deployment

pod sample-onepro-deployment-7669d59cc4-k8g8v owner deployment sample-onepro-deployment

pod sample-onepro-nginx-deployment-7669dd8d46-8fxlw owner deployment sample-onepro-nginx-deployment

pod udger-statefulset-0 owner statefulset udger-statefulset









1 comment: