安全地排空节点
此页面展示如何安全地排空节点,可以选择性地遵守您定义的 PodDisruptionBudget。
开始之前
此任务假设您已满足以下先决条件
- 您不需要在节点排空期间应用程序具有高可用性,或者
- 您已阅读关于 PodDisruptionBudget 的概念,并且已为需要它们的应用程序配置了 PodDisruptionBudget。
(可选)配置中断预算
为确保您的工作负载在维护期间保持可用,您可以配置PodDisruptionBudget。
如果可用性对于在您要排空的节点上运行或可能运行的任何应用程序都很重要,请先配置 PodDisruptionBudgets,然后继续遵循本指南。
建议将 AlwaysAllow
不健康 Pod 驱逐策略 设置为您的 PodDisruptionBudgets,以支持在节点排空期间驱逐行为不端的应用程序。默认行为是等待应用程序 Pod 变为健康,然后才能继续排空。
使用 kubectl drain
从服务中删除节点
您可以使用 kubectl drain
安全地从节点中驱逐所有 Pod,然后对节点执行维护(例如,内核升级、硬件维护等)。安全驱逐允许 Pod 的容器正常终止,并将遵守您指定的 PodDisruptionBudgets。
当 kubectl drain
成功返回时,表示所有 Pod(除了上一段中描述的排除的 Pod)都已安全驱逐(遵守所需的正常终止期限,并遵守您定义的 PodDisruptionBudget)。然后,可以通过关闭其物理机器的电源来安全地关闭节点,或者,如果在云平台上运行,则删除其虚拟机。
注意
如果任何新的 Pod 容忍 node.kubernetes.io/unschedulable
污点,则这些 Pod 可能会被调度到您已排空的节点。除了 DaemonSet 之外,避免容忍该污点。
如果您或另一个 API 用户直接为 Pod 设置了 nodeName
字段(绕过调度程序),则该 Pod 将绑定到指定的节点并在那里运行,即使您已排空该节点并将其标记为不可调度。
首先,确定您要排空的节点的名称。您可以使用以下命令列出集群中的所有节点
kubectl get nodes
接下来,告诉 Kubernetes 排空节点
kubectl drain --ignore-daemonsets <node name>
如果存在由 DaemonSet 管理的 Pod,您需要使用 kubectl
指定 --ignore-daemonsets
才能成功排空节点。kubectl drain
子命令本身实际上不会排空节点的 DaemonSet Pod:DaemonSet 控制器(控制平面的一部分)会立即用新的等效 Pod 替换缺少的 Pod。DaemonSet 控制器还会创建忽略不可调度污点的 Pod,这允许新的 Pod 启动到您正在排空的节点上。
一旦它返回(没有给出错误),您就可以关闭节点电源(或者,如果在云平台上,则删除支持该节点的虚拟机)。如果您在维护操作期间将节点留在集群中,则需要运行
kubectl uncordon <node name>
之后,告诉 Kubernetes 它可以恢复将新 Pod 调度到节点上。
并行排空多个节点
kubectl drain
命令应一次仅发出给一个节点。但是,您可以在不同的终端或后台并行运行多个针对不同节点的 kubectl drain
命令。并发运行的多个排空命令仍将遵守您指定的 PodDisruptionBudget。
例如,如果您有一个具有三个副本的 StatefulSet,并为该集设置了 PodDisruptionBudget,指定 minAvailable: 2
,则只有当所有三个副本 Pod 都健康时,kubectl drain
才会从 StatefulSet 中驱逐一个 Pod;如果然后您并行发出多个排空命令,则 Kubernetes 会遵守 PodDisruptionBudget 并确保在任何给定时间只有 1 个(计算为 replicas - minAvailable
)Pod 不可用。任何会导致健康副本数量低于指定预算的排空都会被阻止。
驱逐 API
如果您不想使用 kubectl drain(例如,为了避免调用外部命令,或为了更精细地控制 Pod 驱逐过程),您也可以使用驱逐 API 以编程方式进行驱逐。
有关更多信息,请参阅API 发起的驱逐。
下一步
- 按照步骤通过配置 Pod 中断预算来保护您的应用程序。