API 发起的驱逐
API 发起的驱逐是指你使用 驱逐 API 来创建 Eviction
对象的过程,该对象会触发 Pod 的优雅终止。
你可以通过直接调用驱逐 API 来请求驱逐,也可以通过 API 服务器 的客户端(如 kubectl drain
命令)以编程方式进行。这会创建一个 Eviction
对象,导致 API 服务器终止 Pod。
API 发起的驱逐会遵循你所配置的 PodDisruptionBudgets
和 terminationGracePeriodSeconds
。
使用 API 为 Pod 创建一个 Eviction 对象,就像对 Pod 执行一个受策略控制的 DELETE
操作一样。
调用驱逐 API
你可以使用 Kubernetes 语言客户端 来访问 Kubernetes API 并创建一个 Eviction
对象。为此,你通过 POST 方法执行尝试的操作,类似于以下示例:
注意
policy/v1
驱逐在 v1.22+ 中可用。在之前的版本中使用 policy/v1beta1
。{
"apiVersion": "policy/v1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
注意
在 v1.22 中已弃用,取而代之的是policy/v1
{
"apiVersion": "policy/v1beta1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
此外,你还可以通过使用 curl
或 wget
访问 API 来尝试驱逐操作,类似于以下示例:
curl -v -H 'Content-type: application/json' https://your-cluster-api-endpoint.example/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json
API 发起的驱逐如何工作
当你使用 API 请求驱逐时,API 服务器会执行准入检查,并以下列方式之一进行响应:
200 OK
:驱逐被允许,创建Eviction
子资源,并删除 Pod,类似于向 Pod URL 发送DELETE
请求。429 Too Many Requests
:由于已配置的 PodDisruptionBudget,当前不允许驱逐。你可能稍后可以再次尝试驱逐。你也可能因为 API 速率限制而看到此响应。500 Internal Server Error
:驱逐不被允许,因为存在配置错误,例如多个 PodDisruptionBudget 引用同一个 Pod。
如果你想要驱逐的 Pod 不属于具有 PodDisruptionBudget 的工作负载,则 API 服务器始终返回 200 OK
并允许驱逐。
如果 API 服务器允许驱逐,Pod 会按如下方式删除:
- API 服务器中的
Pod
资源会更新删除时间戳,此后 API 服务器将Pod
资源视为已终止。Pod
资源还会标记配置的宽限期。 - 运行本地 Pod 的节点上的 kubelet 注意到
Pod
资源被标记为终止,并开始优雅地关闭本地 Pod。 - 当 kubelet 关闭 Pod 时,控制平面会将 Pod 从 EndpointSlice 对象中移除。因此,控制器不再将 Pod 视为有效对象。
- 在 Pod 的宽限期过期后,kubelet 会强制终止本地 Pod。
- kubelet 通知 API 服务器移除
Pod
资源。 - API 服务器删除
Pod
资源。
排查卡住的驱逐
在某些情况下,你的应用程序可能会进入故障状态,其中驱逐 API 只会返回 429
或 500
响应,直到你进行干预。例如,如果 ReplicaSet 为你的应用程序创建了 Pod,但新 Pod 未进入 Ready
状态,则可能会发生这种情况。在上次驱逐的 Pod 具有较长终止宽限期的情况下,你可能也会注意到这种行为。
如果你发现驱逐卡住,请尝试以下解决方案之一:
- 中止或暂停导致问题的自动化操作。在重新启动操作之前,调查卡住的应用程序。
- 等待一段时间,然后直接从集群控制平面删除 Pod,而不是使用驱逐 API。
下一步
- 了解如何使用 Pod 中断预算 保护你的应用程序。
- 了解 节点压力驱逐。
- 了解 Pod 优先级和抢占。