驅逐是指 Kubernetes 從叢集中移除正在執行的 Pod 的過程。這可以透過 API 主動進行,也可以由 kubelet 作為對節點壓力做出反應而自動進行。
在 Kubernetes 中主要有兩種類型來驅逐 Pod:
API-initiated Eviction: 您可以使用 Eviction API 來觸發 Pod 的驅逐,這會走入 Graceful Termination。藉由 API Object 觸發的驅逐都屬於這類型,例如 HPA 以及 Deploy,還有常見於 Kubernetes 升級時候的 kubectl drain。
Node-Pressure Eviction: 當 Node 上的資源,例如記憶體、磁碟空間或檔案系統 inode,消耗到特定級別時,kubelet 會主動終止 Pod 以回收資源。這個行為被稱為 Node-Pressure Eviction。
當你用 Eviction API 來觸發 Pod 的驅逐,這會走入 Graceful Termination。藉由 API Object 觸發的驅逐都屬於這類型,例如 HPA 以及 Deploy,還有常見於 Kubernetes 升級時候的 kubectl drain。
API-initiated Eviction 會遵守 PodDisruptionBudget 和 terminationGracePeriodSeconds。
當請求 API-initiated Eviction,API Server 會執行檢查,並以以下其中一種 HTTP states 回應:
200 OK:允許 Eviction 並建立 Eviction subresource,並刪除 Pod。
429 Too Many Requests:
由於設定的 PodDisruptionBudget,目前不允許驅逐。 您可以稍後再嘗試驅逐。
由於 API 速率限制,可能會看到此回應。
500 Internal Server Error:不允許驅逐,因為設定錯誤,例如多個 PodDisruptionBudget 參考同一個 Pod。
如果要驅逐的 Pod 不屬於 PodDisruptionBudget,則 API Server 一律會傳回 200 OK 並允許驅逐。
如果 API Server 允許驅逐,則 Pod 會按以下步驟刪除:
API Server 中的 Pod 會被打上 delete timestamp,之後 API Server 會將 Pod 視為已終止。 Pod 也會標記為設定的 Grace Period。
執行本機 Pod 的節點上的 kubelet 會注意到 Pod 已標記為終止,並開始 Gracefully Shutdown 本機 Pod。
當 kubelet 關閉 Pod 時,Control 會從 Endpoint 以及 EndpointSlice 中移除 Pod。 因此,Controller 不再將 Pod 視為有效物件。
Pod 的 Grace Period 到期後,kubelet 會 forcefully terminates Pod。
kubelet 告知 API Server 已刪除 Pod。
API Server 會刪除 Pod。
先用 kubectl proxy 把 api-server 暴露出來
kubectl proxy
呼叫 Pod resources 中的 subresources
#!/bin/bash
# Define variables for the pod name and namespace
# REMINDER: Replace the pod name as you want
pod_name="nginx-77b4fdf86c-vfqbc"
namespace="default"
# Create the eviction payload as a JSON object
eviction_payload=$(cat <<EOF
{
"apiVersion": "policy/v1",
"kind": "Eviction",
"metadata": {
"name": "${pod_name}",
"namespace": "${namespace}"
}
}
EOF
)
# Send the eviction request using curl
curl -X POST \
-H "Content-Type: application/json" \
-d "${eviction_payload}" \
http://localhost:8001/api/v1/namespaces/${namespace}/pods/${pod_name}/eviction
不是,Preemption 是直接用 HTTP method Delete Pod,而不是呼叫 Eviction Subresource
文件沒說,所以請看 code
由於傳入的 delelteoptions 是空的,所以吃 pod.spec 裡面的 terminationGracePeriodSeconds
關於 PDB,前面有提到,Preemption 會尊重,但不保證遵守。
由於 Node-Pressure Eviction 行為跟 API-initiated Eviction 完全不同,又牽扯到 QoS 以及 Eviction thresholds,所以下一章單獨講。