API 发起的驱逐
API 发起的驱逐是指使用 Eviction API 创建一个 Eviction
对象,从而触发优雅的 Pod 终止的过程。
你可以直接调用 Eviction API 来请求驱逐,或者通过 API 服务器 的客户端以编程方式进行,例如使用 kubectl drain
命令。这会创建一个 Eviction
对象,进而导致 API 服务器终止该 Pod。
API 发起的驱逐遵循你配置的 PodDisruptionBudgets
和 terminationGracePeriodSeconds
。
使用 API 为 Pod 创建 Eviction 对象,就像对 Pod 执行一次策略控制的 DELETE
操作。
调用 Eviction API
你可以使用 Kubernetes 语言客户端 来访问 Kubernetes API 并创建一个 Eviction
对象。为此,你需要 POST 你尝试的操作,类似于以下示例:
注意
policy/v1
Eviction 在 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 时,控制平面会从 EndpointSlice 对象中移除该 Pod。因此,控制器不再将该 Pod 视为有效对象。
- Pod 的宽限期到期后,kubelet 会强制终止本地 Pod。
- kubelet 通知 API 服务器移除
Pod
资源。 - API 服务器删除
Pod
资源。
驱逐卡住故障排查
在某些情况下,你的应用可能会进入异常状态,此时 Eviction API 将只会返回 429
或 500
响应,直到你进行干预。例如,当 ReplicaSet 为你的应用创建 Pod 但新 Pod 未进入 Ready
状态时,可能会发生这种情况。当最后一个被驱逐的 Pod 有一个很长的终止宽限期时,你也可能注意到这种行为。
如果你注意到驱逐卡住,请尝试以下解决方案之一:
- 中止或暂停导致该问题的自动化操作。在重新启动操作之前,调查卡住的应用。
- 等待一段时间,然后直接从集群控制平面删除 Pod,而不是使用 Eviction API。
接下来
- 了解如何使用 PodDisruptionBudget 来保护你的应用。
- 了解 节点压力驱逐。
- 了解 Pod 优先级和抢占。