安全地清空节点
此页面展示了如何安全地清空 节点,可以选择性地遵守您定义的 PodDisruptionBudget。
开始之前
此任务假定您已满足以下先决条件
- 您不需要应用程序在节点清空期间保持高可用性,或者
- 您已阅读有关 PodDisruptionBudget 概念,并且已为需要它的应用程序 配置了 PodDisruptionBudget。
(可选) 配置中断预算
为确保您的工作负载在维护期间保持可用,您可以配置 PodDisruptionBudget。
如果可用性对于在您要清空的节点上运行或可能运行的任何应用程序很重要,请先 配置 PodDisruptionBudget,然后继续按照本指南操作。
建议将 AlwaysAllow
非健康 Pod 驱逐策略 设置为您的 PodDisruptionBudget,以支持在节点清空期间驱逐行为异常的应用程序。默认行为是等待应用程序 Pod 变得 健康,然后才能继续清空。
使用 kubectl drain
从服务中移除节点
您可以使用 kubectl drain
在对节点进行维护(例如内核升级、硬件维护等)之前安全地从节点中驱逐所有 Pod。安全驱逐允许 Pod 的容器 优雅地终止,并将尊重您指定的 PodDisruptionBudget。
当 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
命令。多个并行运行的 drain 命令仍然会尊重您指定的 PodDisruptionBudget。
例如,如果您有一个包含三个副本的 StatefulSet,并且已为该集设置了一个 PodDisruptionBudget,该预算指定 minAvailable: 2
,那么 kubectl drain
仅在所有三个副本 Pod 都 健康 时才会从 StatefulSet 中驱逐 Pod;如果您随后并行发出多个 drain 命令,Kubernetes 会尊重 PodDisruptionBudget 并确保在任何给定时间仅 1 个(计算为 replicas - minAvailable
)Pod 不可使用。任何会导致 健康 副本数量低于指定预算的 drain 都会被阻止。
驱逐 API
如果您不想使用 kubectl drain(例如,为了避免调用外部命令,或为了更精细地控制 Pod 驱逐过程),您也可以使用驱逐 API 以编程方式引起驱逐。
有关更多信息,请参阅 API 启动的驱逐。
下一步
- 按照步骤通过 配置 PodDisruptionBudget 来保护您的应用程序。