zl程序教程

您现在的位置是:首页 >  Java

当前栏目

k8sailor - 17 Pod 的运行状态 阶段(phase)与状态(status) 探究

2023-02-18 16:39:37 时间

Pod 的生命周期 https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/

Pod 的 Status 不是 Phase。

Pod 的 Status 需要根据 Pod 中的 ContainerStatuses 进行计算得到。

Phase

Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间,

其中 Running 阶段包含了很多行为, 如 1. 下载镜像,2. 启动并初始化,3. 对外提供服务, 而通常认为的 Pod 处于正常服务状态(1. 能接受请求或发送请求, 2. pod 不退出) 只能该阶段的一部分,算 3.对外提供服务。

虽然 kubectl 工具使用 kubectl get pod 可以查看到 Status 这个状态。

→ kgp
NAME                            READY   STATUS             RESTARTS   AGE
my-nginx-6-5f55fd588f-pzn5m     1/1     Running            0          2d3h
new-nginx-04-5f94fffcdc-2gkbd   1/1     Running            0          44h
new-nginx-04-5f94fffcdc-wbnnw   1/1     Running            0          44h
new-nginx-05-799c589bdc-84tf2   1/2     CrashLoopBackOff   527        44h
new-nginx-03-69bd55dc6d-5c8d6   1/2     CrashLoopBackOff   472        40h

k8s api 中并没有直接给出 Pod 的实际状态, 虽然 Pod 的 Status 字段中有 Reason 和 Message 两个字段,但其内容一直为空,暂时没有发现有什么用处。

// k8s.io/api@v0.21.4/core/v1/types.go
type PodStatus struct {
	// A human readable message indicating details about why the pod is in this condition.
	// +optional
	Message string `json:"message,omitempty" protobuf:"bytes,3,opt,name=message"`
	// A brief CamelCase message indicating details about why the pod is in this state.
	// e.g. 'Evicted'
	// +optional
	Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
}

因此, 如果要实现类似 kubectl 展示 Pod Status 的情况, 就需要自己去 PodConditions 中去 获取所有 Container 状态 并分析、计算、返回。顺便提一句, 这里并不知道 kubectl 是怎么实现的, interface 太多,不知道怎么追踪。真失败 T.T 。

根据 Container 状态获取 Pod 状态

// extractPod 转换成业务本身的 Pod
func extractPod(item corev1.Pod) *Pod {

	reason := ""
	message := ""
    
    // 计算 Pod 在 Phase Running 时候的真实 Status
	for _, status := range item.Status.ContainerStatuses {
		if !status.Ready && status.State.Waiting != nil {
			reason = status.State.Waiting.Reason
			message = status.State.Waiting.Message
			break
		}
	}

	return &Pod{
		Name:       item.Name,
		Namespace:  item.Namespace,
		Images:     PodImages(item.Spec),
		NodeName:   item.Spec.NodeName,
		NodeIp:     item.Status.HostIP,
		CreateTime: item.CreationTimestamp.Time,
		PodIP:      item.Status.PodIP,
		Status: PodStatus{
			Phase:   item.Status.Phase,
			Message: message,
			Reason:  reason,
		},
		Labels: item.Labels,
	}
}