我正在尝试使用 Kubernetes 客户端-go 来访问集群中的 pod 详细信息。
我想使用它来获取在一个特定命名空间中运行的 pod 的详细信息,类似于kubectl get pods -n <my namespace>
.
我想要的细节是吊舱的name
、status
、ready
、restarts
和age
。
如何获取这些数据?
因此,我编写了一个函数,该函数接收一个 Kubernetes 客户端(有关制作 client-go 的详细信息)和一个命名空间,并返回所有可用的 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>
时获得的数据完全相同的数据。
除了 Navendu 的出色答案之外,有时当您运行kubectl get pods
与podStatus.Phase
时,"状态"列会有所不同。
如下所述:如何使用 kubernetes go-client 获取与 kubectl 相同的 Pod 状态信息。有时,您需要 Pod 中的特定容器未启动或是否正在初始化的实际原因。
要了解原因,请将 Navendu 的代码更新为:
// 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})
}
请注意,这是一种与源代码执行相同操作的更直接的方法: https://github.com/kubernetes/kubectl/blob/81cffe129f76292f24be1d05435c8d35e975f765/pkg/describe/describe.go#L2013
看起来 kubectl 正在将最终结果抽象给编写器,并且看起来编写器正在封装有关终止代码、时间等的数据。
你可以更新你的代码,使其或多或少相同,但Waiting.Reason/Terminating.Reason对我来说就足够了。