How to use the kubernetes go-client to get the same Pod status i

ghz 7months ago ⋅ 135 views

How to use the kubernetes go-client to get the same Pod status info that kubectl gives

Using the kubernetes go-client (k8s.io/client-go/kubernetes), I know how to get pod.Status and I find the pod.Status.Phase useful (docs). For example, I can output the Pod Status Phase of all Pods using this:

    ...
    api := clientset.CoreV1()
    pods, err := api.Pods("").List(metav1.ListOptions{})
    for i, pod := range pods.Items {
        podstatusPhase := string(pod.Status.Phase)
        podCreationTime := pod.GetCreationTimestamp()
        age := time.Since(podCreationTime.Time).Round(time.Second)

        podInfo := fmt.Sprintf("[%d] Pod: %s, Phase: %s , Created: %s, Age: %s", i, pod.GetName(), podstatusPhase, podCreationTime, age.String())
        fmt.Println(podInfo)
    }

However, the phase is a little simplistic in that it only ever shows 5 values (Pending, Running, Succeeded, Failed, Unknown). I'd rather get the same info that kubectl get pods gives in the Status column, for example:

$ kubectl get pods

NAME                                        READY   STATUS              RESTARTS   AGE     IP             NODE                           NOMINATED NODE   READINESS GATES
moby-dick-cron-scheduler-1564578660-bg4sb   0/2     ContainerCreating   0          178m    <none>         ip-10-30-13-151.ec2.internal   <none>           <none>
notifications-missed-calls-1564564740-js762 0/2     Init:0/1            0          6h49m   <none>         ip-10-30-13-6.ec2.internal     <none>           <none>
antivirus-scanner-cron-1564576740-sd6hh     0/2     Completed           0          3h30m   10.30.13.169   ip-10-30-13-151.ec2.internal   <none>           <none>

In particular, I'm interested in Init:0/1 and PodInitializing statuses. The Pods in these statuses just show as "Pending" when using pod.Status.Phase.

  • Init:0/1 means the Pod has 1 Init containers and 0 have completed successfully so far. init containers run before app containers are started.
  • PodInitializing means the Pod has already finished executing Init Containers.

Is there a way to get a Status such as Init:0/1 using k8s.io/client-go/kubernetes? or is there no short-cut, and I'd need to re-calculate it the same way kubectl does? I guess it uses Pod Status Conditions and container statuses to build the info. If I need to re-calculate it, maybe I can use the kubectl sourcecode? Does anyone know where I can find the relevant bit? (I have very limited golang experience)

Answers

To get more detailed pod status information, including the statuses like Init:0/1 and PodInitializing, you need to inspect the pod's container statuses and conditions in addition to the phase. The kubectl command fetches this detailed information and formats it for display.

In the Kubernetes Go client (k8s.io/client-go/kubernetes), you can access this detailed information by inspecting the pod.Status.ContainerStatuses and pod.Status.Conditions fields. You'll need to iterate through these to gather the relevant information.

Here's how you can modify your code to include more detailed pod status information:

api := clientset.CoreV1()
pods, err := api.Pods("").List(metav1.ListOptions{})
if err != nil {
    // handle error
}

for i, pod := range pods.Items {
    podStatus := ""
    // Check container statuses
    for _, containerStatus := range pod.Status.ContainerStatuses {
        if containerStatus.State.Waiting != nil {
            podStatus += fmt.Sprintf("Container %s is waiting: %s\n", containerStatus.Name, containerStatus.State.Waiting.Reason)
        } else if containerStatus.State.Running != nil {
            podStatus += fmt.Sprintf("Container %s is running\n", containerStatus.Name)
        } else if containerStatus.State.Terminated != nil {
            podStatus += fmt.Sprintf("Container %s is terminated: %s\n", containerStatus.Name, containerStatus.State.Terminated.Reason)
        }
    }

    // Check pod conditions
    for _, condition := range pod.Status.Conditions {
        if condition.Type == corev1.PodInitialized {
            podStatus += fmt.Sprintf("Pod is initialized\n")
        }
        if condition.Type == corev1.PodReady {
            podStatus += fmt.Sprintf("Pod is ready\n")
        }
    }

    podCreationTime := pod.GetCreationTimestamp()
    age := time.Since(podCreationTime.Time).Round(time.Second)

    podInfo := fmt.Sprintf("[%d] Pod: %s\nStatus: %s\nCreated: %s\nAge: %s\n", i, pod.GetName(), podStatus, podCreationTime, age.String())
    fmt.Println(podInfo)
}

In this code:

  • We iterate over each pod's container statuses and conditions to gather detailed status information.
  • We append the status information for each container to the podStatus variable.
  • We append the pod initialization and readiness status to the podStatus variable.
  • We then print out the detailed pod information.

This approach should provide you with more detailed pod status information similar to what kubectl get pods displays. Adjust the formatting and information collected as needed for your use case.