Kubernetes go-client列出pod详细信息,类似于'kubectl get pod'

zzzyeukh  于 2022-12-11  发布在  Kubernetes
关注(0)|答案(2)|浏览(181)

我正在尝试使用Kubernetes client-go访问集群中的pod详细信息。
我想用它来获取在一个特定名称空间(类似于kubectl get pods -n <my namespace>)中运行的pod的详细信息。
我需要的详细信息是pod的namestatusreadyrestartsage
我怎样才能获得这些数据?

b4wnujal

b4wnujal1#

因此,我编写了一个函数,该函数接受Kubernetes客户端(有关创建客户端的详细信息,请参阅客户端)和名称空间,并返回所有可用的pod-

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
}

在得到所有的pod之后,我使用一个循环来运行所有的pod和每个pod内的容器,并手动得到我所需要的所有数据-

// 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})
            }

这将产生与运行kubectl get pods -n <my namespace>时完全相同的数据。

o8x7eapl

o8x7eapl2#

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.

相关问题