Reputation: 335
I'm trying to use the Kubernetes client-go to access pod details in a cluster.
I want to use it to get the details of pods running in one particular namespace, similar to kubectl get pods -n <my namespace>
.
The details I want are the name
, status
, ready
, restarts
and age
of the pod.
How can I get those data?
Upvotes: 4
Views: 3901
Reputation: 429
Adding on to Navendu's excellent answer, sometimes there is a difference in the "STATUS" column when you run kubectl get pods
vs. the podStatus.Phase
.
As described here: How to use the kubernetes go-client to get the same Pod status info that kubectl gives. Sometimes you want the actual reason why a specific container in a pod is not booting up or if it's initializing.
To get the reason, update Navendu's code to be:
// List all the pods similar to kubectl get pods -n <my namespace>
for _, pod := range podList.Items {
// Calculate the age of the pod
podCreationTime := pod.GetCreationTimestamp()
age := time.Since(podCreationTime.Time).Round(time.Second)
// Get the status of each of the pods
podStatus := pod.Status
var containerRestarts int32
var containerReady int
var totalContainers int
var containerReasonNotReady string
// If a pod has multiple containers, get the status from all
for container := range pod.Spec.Containers {
// Updated code to grab actual reason instead of showing just the podStatus
if !podStatus.ContainerStatuses[container].Ready {
if ok := podStatus.ContainerStatuses[container].State.Waiting; ok != nil {
containerReasonNotReady += podStatus.ContainerStatuses[container].State.Waiting.Reason
}
if ok := podStatus.ContainerStatuses[container].State.Terminated; ok != nil {
containerReasonNotReady += podStatus.ContainerStatuses[container].State.Terminated.Reason
}
}
containerRestarts += podStatus.ContainerStatuses[container].RestartCount
if podStatus.ContainerStatuses[container].Ready {
containerReady++
}
totalContainers++
}
// Get the values from the pod status
name := pod.GetName()
ready := fmt.Sprintf("%v/%v", containerReady, totalContainers)
// Updated code to grab actualStatus
var actualStatus string
if len(containerReasonNotReady) > 0 {
actualStatus = containerReasonNotReady
} else {
actualStatus = fmt.Sprintf("%v", podStatus.Phase)
}
restarts := fmt.Sprintf("%v", containerRestarts)
ageS := age.String()
// Append this to data to be printed in a table
data = append(data, []string{name, ready, actualStatus, restarts, ageS})
}
Note that this is a more direct method of doing the same thing as the source code: https://github.com/kubernetes/kubectl/blob/81cffe129f76292f24be1d05435c8d35e975f765/pkg/describe/describe.go#L2013
It seems like kubectl is abstracting the end result to a writer, and it also looks like the writer is encapsulating data about the terminationCode, times, and more.
You can update your code to be more or less the same, but the Waiting.Reason/Terminating.Reason is enough for me.
Upvotes: 1
Reputation: 335
So, I wrote a function that takes in a Kubernetes client (refer the client-go for details on making one) and a namespace and returns all the pods available-
func GetPods(client *meshkitkube.Client, namespace string) (*v1core.PodList, error) {
// Create a pod interface for the given namespace
podInterface := client.KubeClient.CoreV1().Pods(namespace)
// List the pods in the given namespace
podList, err := podInterface.List(context.TODO(), v1.ListOptions{})
if err != nil {
return nil, err
}
return podList, nil
}
After getting all the pods, I used a loop to run through all the pods and containers within each pod and manually got all the data I required-
// List all the pods similar to kubectl get pods -n <my namespace>
for _, pod := range podList.Items {
// Calculate the age of the pod
podCreationTime := pod.GetCreationTimestamp()
age := time.Since(podCreationTime.Time).Round(time.Second)
// Get the status of each of the pods
podStatus := pod.Status
var containerRestarts int32
var containerReady int
var totalContainers int
// If a pod has multiple containers, get the status from all
for container := range pod.Spec.Containers {
containerRestarts += podStatus.ContainerStatuses[container].RestartCount
if podStatus.ContainerStatuses[container].Ready {
containerReady++
}
totalContainers++
}
// Get the values from the pod status
name := pod.GetName()
ready := fmt.Sprintf("%v/%v", containerReady, totalContainers)
status := fmt.Sprintf("%v", podStatus.Phase)
restarts := fmt.Sprintf("%v", containerRestarts)
ageS := age.String()
// Append this to data to be printed in a table
data = append(data, []string{name, ready, status, restarts, ageS})
}
This will result in the exact same data as you would get when running kubectl get pods -n <my namespace>
.
Upvotes: 4