本頁面說明如何在 Google Kubernetes Engine (GKE) Autopilot 叢集中使用現成 Pod,以較低的成本執行容錯工作負載。
總覽
在 GKE Autopilot 叢集中,Spot Pod 是在由 Compute Engine Spot VM 支援的節點上執行的 Pod。Spot Pod 的價格比標準 Autopilot Pod 低,但只要需要運算資源來執行標準 Pod,GKE 就會將 Spot Pod 逐出。
與以標準 Pod 執行這些工作負載相比,Spot Pod 適合以較低的成本執行無狀態、批次或容錯工作負載。如要在 Autopilot 叢集中使用 Spot Pod,請修改資訊清單和 Pod 規格,要求使用 Spot Pod。
您可以在預設的通用 Autopilot 運算類別,以及符合特定硬體需求的專用運算類別上執行 Spot Pod。如要瞭解這些運算類別,請參閱「Autopilot 中的運算類別」。
如要進一步瞭解 Autopilot 叢集中 Spot Pod 的定價,請參閱 Google Kubernetes Engine 定價。
Autopilot 服務水準協議不適用於 Spot Pod。
優點
在 Autopilot 叢集中使用 Spot Pod 可享有下列優點:
- 與在標準 Autopilot Pod 上執行相同工作負載相比,價格較低。
- GKE 會自動管理自動調整資源配置和排程。
- GKE 會自動汙染執行 Spot Pod 的節點,確保標準 Pod (例如重要工作負載) 不會排定在這些節點上。使用 Spot Pod 的部署作業會自動更新,並加入相應的容許度。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
在 Autopilot 工作負載中要求 Spot Pod
如要要求 Pod 以 Spot Pod 形式執行,請在 Pod 規格的 nodeSelector 或 node affinity 中使用 cloud.google.com/gke-spot=true
標籤。GKE 會自動佈建可執行 Spot Pod 的節點。
Spot Pod 可能隨時遭到驅逐並終止,例如 Google Cloud其他位置需要運算資源時。終止作業發生時,終止節點上的 Spot Pod 最多可要求 15 秒的終止寬限期 (系統會盡力提供),方法是指定 terminationGracePeriodSeconds
欄位。
Spot Pods 在搶占期間的寬限期最長為 15 秒。在 terminationGracePeriodSeconds
中要求超過 15 秒的預先搶占時間,不會獲得超過 15 秒的預先搶占時間。Pod 遭到驅逐時,系統會傳送 SIGTERM 訊號給 Pod,Pod 應在寬限期內採取關閉步驟。
如果是 Autopilot,GKE 也會自動汙染為執行 Spot Pod 建立的節點,並使用對應的容許條件修改這些工作負載。這個 taint 會禁止標準 Pod 在執行 Spot Pod 的節點上排程。
使用 nodeSelector 要求 Spot Pod
您可以使用 nodeSelector,在 Deployment 中要求 Spot Pod。在 Deployment 中加入 cloud.google.com/gke-spot=true
標籤,如下列範例所示:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
nodeSelector:
cloud.google.com/gke-spot: "true"
terminationGracePeriodSeconds: 15
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
使用節點相依性要求 Spot Pod
或者,您也可以使用節點親和性要求 Spot Pod。節點親和性提供更具擴充性的方式,可選取節點來執行工作負載。舉例來說,您可以合併多個選取條件,進一步控管 Pod 的執行位置。使用節點相依性要求 Spot Pod 時,可以指定要使用的節點相依性類型,如下所示:
requiredDuringSchedulingIgnoredDuringExecution
:必須使用 Spot Pod。preferredDuringSchedulingIgnoredDuringExecution
:盡量使用 Spot Pod。
如要使用節點親和性在 Deployment 中要求 Spot Pod,請將下列 nodeAffinity
規則新增至 Deployment 資訊清單:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
terminationGracePeriodSeconds: 15
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/gke-spot
operator: In
values:
- "true"
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
盡量要求 Spot Pod
如要使用節點相依性盡可能要求 Spot Pod,請使用 preferredDuringSchedulingIgnoredDuringExecution
。如果您要求優先使用 Spot Pod,GKE 會依下列順序排程 Pod:
- 現有節點可執行 Spot Pod,且有可分配的容量。
- 現有的標準節點,且有可分配的容量。
- 如果運算資源充足,可執行 Spot Pod 的新節點。
- 新的標準節點。
由於 GKE 偏好使用具有可分配容量的現有標準節點,而不是為 Spot Pod 建立新節點,因此您可能會發現以標準 Pod 執行的 Pod 數量多於 Spot Pod,導致您無法充分利用 Spot Pod 的低價優勢。
先占 Pod 的要求
Autopilot 叢集支援使用 cloud.google.com/gke-preemptible
選取器要求可搶占的 Pod。使用這個選取器的 Pod 會自動遷移至 Spot Pod,選取器也會變更為 cloud.google.com/gke-spot
。
尋找並刪除終止的 Pod
在 Pod 正常終止期間,kubelet 會為終止的 Pod 指派 Failed
狀態和 Shutdown
原因。當終止的 Pod 數量達到 1000 個的門檻時,垃圾收集會清除 Pod。您也可以使用下列指令手動刪除關機的 Pod:
kubectl get pods --all-namespaces | grep -i shutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
停止工作負載使用 Spot Pod
如要更新現有的 Spot Pod,讓這些 Pod 以標準 Pod 形式執行,請使用下列其中一種方法:
- 重新建立工作負載:刪除 Deployment、移除資訊清單中選取 Spot Pod 的行,然後將更新後的 Deployment 資訊清單套用至叢集。
- 編輯工作負載:在叢集中執行 Pod 時編輯 Deployment 規格。
使用這兩種方法時,工作負載可能會稍微中斷。
重新建立工作負載
下列步驟說明如何刪除現有 Deployment,並將更新後的資訊清單套用至叢集。您也可以對其他類型的 Kubernetes 工作負載 (例如 Jobs) 執行這些步驟。
為確保 GKE 將更新後的 Pod 放置在正確類型的節點上,您必須將工作負載的現有狀態從 Kubernetes API 伺服器匯出至檔案,並編輯該檔案。
將工作負載規格寫入 YAML 檔案:
kubectl get deployment DEPLOYMENT_NAME -o yaml > DEPLOYMENT_NAME-on-demand.yaml
將
DEPLOYMENT_NAME
換成部署作業的名稱。如果是其他類型的工作負載 (例如 Job 或 Pod),請在kubectl get
指令中使用對應的資源名稱,例如kubectl get pod
。在文字編輯器中開啟 YAML 檔案:
vi DEPLOYMENT_NAME-on-demand.yaml
從檔案中移除 Spot Pod 的 nodeSelector 和 GKE 為 Spot Pod 新增的容許條件:
apiVersion: apps/v1 kind: Deployment metadata: annotations: # lines omitted for clarity spec: progressDeadlineSeconds: 600 replicas: 6 revisionHistoryLimit: 10 selector: matchLabels: pod: nginx-pod strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: # lines omitted for clarity spec: containers: - image: nginx imagePullPolicy: Always name: web-server resources: limits: ephemeral-storage: 1Gi requests: cpu: 500m ephemeral-storage: 1Gi memory: 2Gi securityContext: capabilities: drop: - NET_RAW terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst nodeSelector: cloud.google.com/gke-spot: "true" restartPolicy: Always schedulerName: default-scheduler securityContext: seccompProfile: type: RuntimeDefault terminationGracePeriodSeconds: 15 tolerations: - effect: NoSchedule key: kubernetes.io/arch operator: Equal value: amd64 - effect: NoSchedule key: cloud.google.com/gke-spot operator: Equal value: "true" status: #lines omitted for clarity
您必須移除容許條件和 nodeSelector,向 GKE 指出 Pod 必須在隨選節點上執行,而非在 Spot 節點上執行。
儲存更新後的資訊清單。
刪除 Deployment 資訊清單,然後重新套用至叢集:
kubectl replace -f DEPLOYMENT_NAME-on-demand.yaml
這項作業所需時間取決於 GKE 需要終止及清除的 Pod 數量。
就地編輯工作負載
下列步驟說明如何就地編輯執行中的 Deployment,向 GKE 指出 Pod 必須在隨選節點上執行。您也可以將這些步驟用於其他類型的 Kubernetes 工作負載,例如 Jobs。
您必須在 Kubernetes API 中編輯工作負載物件,因為 GKE 會在工作負載許可期間,自動將 Spot Pod 的容許度新增至工作負載規格。
在文字編輯器中開啟工作負載資訊清單進行編輯:
kubectl edit deployment/DEPLOYMENT_NAME
將
DEPLOYMENT_NAME
替換為 Deployment 的名稱。如果是其他類型的工作負載 (例如 Job 或 Pod),請在kubectl edit
指令中使用對應的資源名稱,例如kubectl edit pod/POD_NAME
。在文字編輯器中,刪除 Spot Pod 的節點選取器或節點親和性規則,以及 GKE 新增至資訊清單的容許條件,如下列範例所示:
apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment namespace: default spec: replicas: 1 selector: matchLabels: type: dev template: metadata: labels: type: dev spec: nodeSelector: cloud.google.com/gke-spot: "true" tolerations: - effect: NoSchedule key: cloud.google.com/gke-spot operator: Equal value: "true" containers: - name: nginx image: nginx ports: - containerPort: 80
儲存更新後的資訊清單,然後關閉文字編輯器。更新後的物件設定會向 GKE 指出,Pod 必須在隨選節點上執行。GKE 會重新建立 Pod,並將其放置在新的隨選節點上。
確認工作負載在隨選節點上執行
如要確認更新後的工作負載不再於 Spot Pod 上執行,請檢查工作負載並尋找 Spot Pod 的容錯:
檢查工作負載:
kubectl describe deployment DEPLOYMENT_NAME
輸出內容不會在 spec.tolerations
欄位中顯示 cloud.google.com/gke-spot
的項目。