diff --git a/content/zh-cn/docs/concepts/architecture/nodes.md b/content/zh-cn/docs/concepts/architecture/nodes.md index 039ca181adac9..db4ac045f49bd 100644 --- a/content/zh-cn/docs/concepts/architecture/nodes.md +++ b/content/zh-cn/docs/concepts/architecture/nodes.md @@ -553,464 +553,6 @@ for more information. `kubelet` 可以在作出资源分配决策时使用拓扑提示。 参考[控制节点上拓扑管理策略](/zh-cn/docs/tasks/administer-cluster/topology-manager/)了解详细信息。 - -## 节点体面关闭 {#graceful-node-shutdown} - -{{< feature-state feature_gate_name="GracefulNodeShutdown" >}} - - -kubelet 会尝试检测节点系统关闭事件并终止在节点上运行的所有 Pod。 - -在节点终止期间,kubelet 保证 Pod 遵从常规的 -[Pod 终止流程](/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination), -且不接受新的 Pod(即使这些 Pod 已经绑定到该节点)。 - - -节点体面关闭特性依赖于 systemd,因为它要利用 -[systemd 抑制器锁](https://www.freedesktop.org/wiki/Software/systemd/inhibit/)机制, -在给定的期限内延迟节点关闭。 - - -节点体面关闭特性受 `GracefulNodeShutdown` -[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)控制, -在 1.21 版本中是默认启用的。 - - -注意,默认情况下,下面描述的两个配置选项,`shutdownGracePeriod` 和 -`shutdownGracePeriodCriticalPods` 都是被设置为 0 的,因此不会激活节点体面关闭功能。 -要激活此功能特性,这两个 kubelet 配置选项要适当配置,并设置为非零值。 - - -一旦 systemd 检测到或通知节点关闭,kubelet 就会在节点上设置一个 -`NotReady` 状况,并将 `reason` 设置为 `"node is shutting down"`。 -kube-scheduler 会重视此状况,不将 Pod 调度到受影响的节点上; -其他第三方调度程序也应当遵循相同的逻辑。这意味着新的 Pod 不会被调度到该节点上, -因此不会有新 Pod 启动。 - - -如果检测到节点关闭过程正在进行中,kubelet **也会**在 `PodAdmission` -阶段拒绝 Pod,即使是该 Pod 带有 `node.kubernetes.io/not-ready:NoSchedule` -的{{< glossary_tooltip text="容忍度" term_id="toleration" >}}。 - - -同时,当 kubelet 通过 API 在其 Node 上设置该状况时,kubelet -也开始终止在本地运行的所有 Pod。 - - -在体面关闭节点过程中,kubelet 分两个阶段来终止 Pod: - -1. 终止在节点上运行的常规 Pod。 -2. 终止在节点上运行的[关键 Pod](/zh-cn/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical)。 - - -节点体面关闭的特性对应两个 -[`KubeletConfiguration`](/zh-cn/docs/tasks/administer-cluster/kubelet-config-file/) 选项: - -* `shutdownGracePeriod`: - * 指定节点应延迟关闭的总持续时间。此时间是 Pod 体面终止的时间总和,不区分常规 Pod - 还是[关键 Pod](/zh-cn/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical)。 -* `shutdownGracePeriodCriticalPods`: - * 在节点关闭期间指定用于终止[关键 Pod](/zh-cn/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical) - 的持续时间。该值应小于 `shutdownGracePeriod`。 - -{{< note >}} - -在某些情况下,节点终止过程会被系统取消(或者可能由管理员手动取消)。 -无论哪种情况下,节点都将返回到 `Ready` 状态。然而,已经开始终止进程的 -Pod 将不会被 kubelet 恢复,需要被重新调度。 -{{< /note >}} - - -例如,如果设置了 `shutdownGracePeriod=30s` 和 `shutdownGracePeriodCriticalPods=10s`, -则 kubelet 将延迟 30 秒关闭节点。 -在关闭期间,将保留前 20(30 - 10)秒用于体面终止常规 Pod, -而保留最后 10 秒用于终止[关键 Pod](/zh-cn/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical)。 - -{{< note >}} - -当 Pod 在正常节点关闭期间被驱逐时,它们会被标记为关闭。 -运行 `kubectl get pods` 时,被驱逐的 Pod 的状态显示为 `Terminated`。 -并且 `kubectl describe pod` 表示 Pod 因节点关闭而被驱逐: - -``` -Reason: Terminated -Message: Pod was terminated in response to imminent node shutdown. -``` -{{< /note >}} - - -### 基于 Pod 优先级的节点体面关闭 {#pod-priority-graceful-node-shutdown} - -{{< feature-state feature_gate_name="GracefulNodeShutdownBasedOnPodPriority" >}} - - -为了在节点体面关闭期间提供更多的灵活性,尤其是处理关闭期间的 Pod 排序问题, -节点体面关闭机制能够关注 Pod 的 PriorityClass 设置,前提是你已经在集群中启用了此功能特性。 -此功能特性允许集群管理员基于 Pod -的[优先级类(Priority Class)](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass) -显式地定义节点体面关闭期间 Pod 的处理顺序。 - - -前文所述的[节点体面关闭](#graceful-node-shutdown)特性能够分两个阶段关闭 Pod, -首先关闭的是非关键的 Pod,之后再处理关键 Pod。 -如果需要显式地以更细粒度定义关闭期间 Pod 的处理顺序,需要一定的灵活度, -这时可以使用基于 Pod 优先级的体面关闭机制。 - - -当节点体面关闭能够处理 Pod 优先级时,节点体面关闭的处理可以分为多个阶段, -每个阶段关闭特定优先级类的 Pod。kubelet 可以被配置为按确切的阶段处理 Pod, -且每个阶段可以独立设置关闭时间。 - - -假设集群中存在以下自定义的 Pod -[优先级类](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass)。 - -| Pod 优先级类名称 | Pod 优先级类数值 | -|-------------------------|------------------------| -|`custom-class-a` | 100000 | -|`custom-class-b` | 10000 | -|`custom-class-c` | 1000 | -|`regular/unset` | 0 | - - -在 [kubelet 配置](/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/)中, -`shutdownGracePeriodByPodPriority` 可能看起来是这样: - -| Pod 优先级类数值 | 关闭期限 | -|------------------------|-----------| -| 100000 | 10 秒 | -| 10000 | 180 秒 | -| 1000 | 120 秒 | -| 0 | 60 秒 | - - -对应的 kubelet 配置 YAML 将会是: - -```yaml -shutdownGracePeriodByPodPriority: - - priority: 100000 - shutdownGracePeriodSeconds: 10 - - priority: 10000 - shutdownGracePeriodSeconds: 180 - - priority: 1000 - shutdownGracePeriodSeconds: 120 - - priority: 0 - shutdownGracePeriodSeconds: 60 -``` - - -上面的表格表明,所有 `priority` 值大于等于 100000 的 Pod 会得到 10 秒钟期限停止, -所有 `priority` 值介于 10000 和 100000 之间的 Pod 会得到 180 秒钟期限停止, -所有 `priority` 值介于 1000 和 10000 之间的 Pod 会得到 120 秒钟期限停止, -所有其他 Pod 将获得 60 秒的时间停止。 - -用户不需要为所有的优先级类都设置数值。例如,你也可以使用下面这种配置: - -| Pod 优先级类数值 | 关闭期限 | -|------------------------|-----------| -| 100000 | 300 秒 | -| 1000 | 120 秒 | -| 0 | 60 秒 | - - -在上面这个场景中,优先级类为 `custom-class-b` 的 Pod 会与优先级类为 `custom-class-c` -的 Pod 在关闭时按相同期限处理。 - -如果在特定的范围内不存在 Pod,则 kubelet 不会等待对应优先级范围的 Pod。 -kubelet 会直接跳到下一个优先级数值范围进行处理。 - - -如果此功能特性被启用,但没有提供配置数据,则不会出现排序操作。 - -使用此功能特性需要启用 `GracefulNodeShutdownBasedOnPodPriority` -[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), -并将 [kubelet 配置](/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/) -中的 `shutdownGracePeriodByPodPriority` 设置为期望的配置, -其中包含 Pod 的优先级类数值以及对应的关闭期限。 - -{{< note >}} - -在节点体面关闭期间考虑 Pod 优先级的能力是作为 Kubernetes v1.23 中的 Alpha 功能引入的。 -在 Kubernetes {{< skew currentVersion >}} 中该功能是 Beta 版,默认启用。 -{{< /note >}} - - -kubelet 子系统中会生成 `graceful_shutdown_start_time_seconds` 和 -`graceful_shutdown_end_time_seconds` 度量指标以便监视节点关闭行为。 - - -## 处理节点非体面关闭 {#non-graceful-node-shutdown} - -{{< feature-state feature_gate_name="NodeOutOfServiceVolumeDetach" >}} - - -节点关闭的操作可能无法被 kubelet 的节点关闭管理器检测到, -是因为该命令不会触发 kubelet 所使用的抑制锁定机制,或者是因为用户错误的原因, -即 ShutdownGracePeriod 和 ShutdownGracePeriodCriticalPod 配置不正确。 -请参考以上[节点体面关闭](#graceful-node-shutdown)部分了解更多详细信息。 - - -当某节点关闭但 kubelet 的节点关闭管理器未检测到这一事件时, -在那个已关闭节点上、属于 {{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}} -的 Pod 将停滞于终止状态,并且不能移动到新的运行节点上。 -这是因为已关闭节点上的 kubelet 已不存在,亦无法删除 Pod, -因此 StatefulSet 无法创建同名的新 Pod。 -如果 Pod 使用了卷,则 VolumeAttachments 不会从原来的已关闭节点上删除, -因此这些 Pod 所使用的卷也无法挂接到新的运行节点上。 -所以,那些以 StatefulSet 形式运行的应用无法正常工作。 -如果原来的已关闭节点被恢复,kubelet 将删除 Pod,新的 Pod 将被在不同的运行节点上创建。 -如果原来的已关闭节点没有被恢复,那些在已关闭节点上的 Pod 将永远滞留在终止状态。 - - -为了缓解上述情况,用户可以手动将具有 `NoExecute` 或 `NoSchedule` 效果的 -`node.kubernetes.io/out-of-service` 污点添加到节点上,标记其无法提供服务。 -如果在 {{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}} -上启用了 `NodeOutOfServiceVolumeDetach` -[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), -并且节点被通过污点标记为无法提供服务,如果节点 Pod 上没有设置对应的容忍度, -那么这样的 Pod 将被强制删除,并且该在节点上被终止的 Pod 将立即进行卷分离操作。 -这样就允许那些在无法提供服务节点上的 Pod 能在其他节点上快速恢复。 - - -在非体面关闭期间,Pod 分两个阶段终止: - -1. 强制删除没有匹配的 `out-of-service` 容忍度的 Pod。 -2. 立即对此类 Pod 执行分离卷操作。 - -{{< note >}} - -- 在添加 `node.kubernetes.io/out-of-service` 污点之前, - 应该验证节点已经处于关闭或断电状态(而不是在重新启动中)。 -- 将 Pod 移动到新节点后,用户需要手动移除停止服务的污点, - 并且用户要检查关闭节点是否已恢复,因为该用户是最初添加污点的用户。 -{{< /note >}} - - -### 存储超时强制解除挂接 {#storage-force-detach-on-timeout} - -当任何 Pod 未能在 6 分钟内被成功删除时,如果节点当时不健康, -Kubernetes 将强制解除挂接正在被卸载的卷。 -在启用了强制解除挂接卷的节点上仍在运行的所有工作负载都将导致违反 -[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#controllerunpublishvolume), -该规范指出 `ControllerUnpublishVolume` "**必须**在调用卷上的所有 `NodeUnstageVolume` -和 `NodeUnpublishVolume` 执行且成功后被调用"。在这种情况下,相关节点上的卷可能会遇到数据损坏。 - - -强制存储解除挂接行为是可选的;用户可以选择使用"非体面节点关闭"特性。 - - -可以通过在 `kube-controller-manager` 中设置 `disable-force-detach-on-timeout` -配置字段来禁用超时时存储强制解除挂接。 -禁用超时强制解除挂接特性意味着托管在不正常运行时间超过 6 分钟的节点上的卷将不会删除其关联的 -[VolumeAttachment](/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume-attachment-v1/)。 - - -应用此设置后,仍关联到某卷的不健康 Pod 必须通过上述[非体面节点关闭](#non-graceful-node-shutdown)过程进行恢复。 - -{{< note >}} - -- 使用[非体面节点关闭](#non-graceful-node-shutdown)过程时必须小心。 -- 偏离上述步骤可能会导致数据损坏。 -{{< /note >}} -