本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.25:Pod 的 PodHasNetwork 状况

Kubernetes 1.25 在 Pod 的 status 字段中引入了对由 kubelet 管理的新 Pod 状况的 Alpha 支持:PodHasNetwork。工作节点上的 kubelet 将使用 PodHasNetwork 状况,从容器运行时(通常与 CNI 插件协调)创建 Pod 沙箱和配置网络的角度,准确地反映 Pod 的初始化状态。在 PodHasNetwork 状况的状态被设置为 "True" 后,kubelet 开始拉取容器镜像并启动单个容器(包括 Init 容器)。从集群基础设施角度报告 Pod 初始化延迟的指标收集服务(即不考虑每个容器的特性,如镜像大小或有效负载)可以利用 PodHasNetwork 状况来准确地生成服务级别指标(SLI)。某些管理底层 Pod 的 Operator 或控制器可以利用 PodHasNetwork 状况,来优化当 Pod 反复启动失败时所执行的操作集。

Kubernetes 1.28 更新

PodHasNetwork 状况已重命名为 PodReadyToStartContainers。与此同时,特性门控 PodHasNetworkCondition 已被 PodReadyToStartContainersCondition 取代。你需要在 v1.28.0 及更高版本中将 PodReadyToStartContainersCondition 设置为 true 才能使用这一新特性。

这与现有的 Pod 的 Initialized 状况有何不同?

kubelet 根据 Pod 中是否存在 Init 容器来设置 Pod 的 status 字段中报告的现有 Initialized 状况的状态。

如果一个 Pod 指定了 Init 容器,则在该 Pod 的所有 Init 容器都成功运行之前,Pod 状态中的 Initialized 状况的状态不会被设置为 "True"。然而,由用户配置的 Init 容器可能会出错(负载崩溃、镜像无效等),并且在一个 Pod 中配置的 Init 容器数量可能因工作负载的不同而异。因此,集群范围内的、关于 Pod 初始化的基础设施 SLI 不能依赖于 Pod 的 Initialized 状况。

如果一个 Pod 没有指定 Init 容器,则 Pod 状态中的 Initialized 状况的状态会在 Pod 生命周期的很早阶段就被设置为 "True"。这发生在 kubelet 启动任何 Pod 运行时沙箱创建和网络配置步骤之前。因此,一个没有 Init 容器的 Pod 即使容器运行时无法成功初始化 Pod 沙箱环境,其 Initialized 状况的状态也会报告为 "True"

相对于上述两种情况,PodHasNetwork 状况能更准确地反映 Pod 运行时沙箱何时被初始化并配置了网络,以便 kubelet 可以继续在该 Pod 中启动用户配置的容器(包括 Init 容器)。

特殊情况

如果一个 Pod 指定 hostNetwork"True",那么 PodHasNetwork 状况会根据 Pod 沙箱的成功创建而设置为 "True",而忽略 Pod 沙箱的网络配置状态。这是因为当 Pod 的 hostNetwork 设置为 "True" 时,CRI 实现通常会跳过任何 Pod 沙箱网络配置。

节点代理可以通过监视指定附加网络配置的 Pod 注解(例如 k8s.v1.cni.cncf.io/networks)的变化来动态地重新配置 Pod 的网络接口。在 kubelet(与容器运行时协调)初始化 Pod 沙箱后,对 Pod 网络配置的动态更新不会反映在 PodHasNetwork 状况中。

试用 Pod 的 PodHasNetwork 状况

为了让 kubelet 在 Pod 的 status 字段中报告 PodHasNetwork 状况,请在 kubelet 上启用 PodHasNetworkCondition 特性门控。

对于一个其运行时沙箱已成功创建并配置了网络的 Pod,kubelet 将报告 PodHasNetwork 状况,其状态设置为 "True"

$ kubectl describe pod nginx1
Name:             nginx1
Namespace:        default
...
Conditions:
  Type              Status
  PodHasNetwork     True
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

对于一个其运行时沙箱尚未创建(也未配置网络)的 Pod,kubelet 将报告 PodHasNetwork 状况,其状态设置为 "False"

$ kubectl describe pod nginx2
Name:             nginx2
Namespace:        default
...
Conditions:
  Type              Status
  PodHasNetwork     False
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True

下一步是什么?

根据反馈和采用情况,Kubernetes 团队计划在 1.26 或 1.27 版本中将 PodHasNetwork 状况的报告推向 Beta 阶段。

我如何了解更多信息?

请查阅 文档 中关于 PodHasNetwork 状况的内容,以了解更多关于它以及它如何与其他 Pod 状况相适应的信息。

如何参与?

此功能由 SIG Node 社区推动。欢迎加入我们,与社区建立联系,分享你对上述功能及其他方面的想法和反馈。我们期待你的回音!

致谢

我们要感谢以下人员对该功能的 KEP 和 PR 进行了富有洞察力和帮助的审查:Derek Carr (@derekwaynecarr), Mrunal Patel (@mrunalp), Dawn Chen (@dchen1107), Qiutong Song (@qiutongs), Ruiwen Zhao (@ruiwen-zhao), Tim Bannister (@sftim), Danielle Lancashire (@endocrimes) and Agam Dua (@agamdua)。