管理 Google Kubernetes Engine (GKE) Standard 叢集時,節點集區問題可能會中斷重要作業。這些問題可能會導致您無法水平擴展工作負載來滿足需求,或執行必要的基礎架構升級,進而影響應用程式的可靠性。
請參閱本頁內容,排解這些常見的節點集區問題。瞭解如何確認資源是否不足、使用盡力佈建等功能建立節點,以及安全遷移工作負載,避免造成中斷。
這項資訊對於負責管理叢集基礎架構的平台管理員和操作員來說非常重要。應用程式開發人員也能透過這份文件,瞭解節點集區限制對應用程式部署作業的影響。如要進一步瞭解我們在內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。 Google Cloud
節點集區建立問題
本節列出在標準叢集中建立新節點集區時可能會發生的問題,並提供相應的修正建議。
問題:資源不足,無法建立節點集區
在 Google Cloud 區域中建立節點集區時,如果該區域的硬體不足以滿足您的需求,就會發生下列問題。
如要確認節點集區建立失敗的原因是否為可用區資源不足,請查看記錄檔中的相關錯誤訊息。
前往 Google Cloud 控制台的「Logs Explorer」:
在「Query」(查詢) 欄位中,指定下列查詢:
log_id(cloudaudit.googleapis.com/activity) resource.labels.cluster_name="CLUSTER_NAME" protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")將
CLUSTER_NAME替換為 GKE 叢集名稱。點選「執行查詢」。
你可能會看到下列其中一則錯誤訊息:
resource pool exhaustedThe zone does not have enough resources available to fulfill the request. Try a different zone, or try again later.ZONE_RESOURCE_POOL_EXHAUSTEDZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILSMachine type with name 'MACHINE_NAME' does not exist in zone 'ZONE_NAME'
如要解決這個問題,請嘗試下列建議:
- 確認所選 Google Cloud 區域或可用區具備您需要的特定硬體。請參閱 Compute Engine 可用性表格,確認特定可用區是否支援特定硬體。請為節點選擇其他Google Cloud 區域或可用區,或許能更順利取得所需硬體。
- 使用較小的機型建立節點集區。增加節點集區中的節點數量,讓總運算能力維持不變。
- 使用 Compute Engine 容量預留項目預先預留資源。
- 如果系統能從要求的節點數量中,佈建至少指定數量的節點,請使用下一節說明的盡力佈建功能,順利建立節點集區。
盡可能佈建
對於特定硬體,您可以使用盡力佈建,指示 GKE 在至少能佈建指定數量下限的節點時,成功建立節點集區。GKE 會持續嘗試佈建剩餘節點,以滿足原始要求。如要指示 GKE 使用盡力佈建,請使用下列指令:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--node-locations=ZONE1,ZONE2,... \
--machine-type=MACHINE_TYPE
--best-effort-provision \
--min-provision-nodes=MINIMUM_NODES
更改下列內容:
NODE_POOL_NAME:新節點集區的名稱。CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。如果是區域叢集,請提供區域;如果是可用區叢集,請提供可用區。ZONE1,ZONE2,...:節點的 Compute Engine 區域。這些可用區必須支援所選硬體。MACHINE_TYPE:節點的 Compute Engine 引擎機型。例如:a2-highgpu-1g。MINIMUM_NODES:GKE 佈建節點並成功建立節點集區時,所需的節點數量下限。如果省略,預設值為1。
舉例來說,假設您在 us-central1-c 需要 10 個節點,並附加 NVIDIA A100 40 GB GPU。根據 GPU 位置,這個可用區支援 A100 GPU。為避免因無法取得 10 部 GPU 機器而導致節點集區建立失敗,您可以使用盡力佈建功能。
gcloud container node-pools create a100-nodes \
--cluster=ml-cluster \
--location=us-central1 \
--node-locations=us-central1-c \
--num-nodes=10 \
--machine-type=a2-highgpu-1g \
--accelerator=type=nvidia-tesla-a100,count=1 \
--best-effort-provision \
--min-provision-nodes=5
即使 us-central1-c 中只有五個 GPU 可用,GKE 仍會建立節點集區。隨著時間推移,GKE 會嘗試佈建更多節點,直到節點集區中有 10 個節點為止。
錯誤:執行個體不含「instance-template」中繼資料
如果節點集區無法升級、調度資源或執行自動節點修復作業,您可能會看到下列錯誤訊息:
Instance INSTANCE_NAME does not contain 'instance-template' metadata
這項錯誤表示 GKE 分配的 VM 執行個體中繼資料已損毀。如果自訂編寫的自動化動作或指令碼嘗試新增執行個體中繼資料 (例如 block-project-ssh-keys),但除了新增或更新值之外,還刪除現有中繼資料,通常就會發生這種情況。如要瞭解 VM 執行個體中繼資料,請參閱「設定自訂中繼資料」。
如果刪除任何重要中繼資料值 (包括 instance-template、kube-labels、kubelet-config、kubeconfig、cluster-name、configure-sh、cluster-uid 等),節點或整個節點集區可能會進入不穩定狀態,因為這些值對 GKE 作業至關重要。
如果執行個體中繼資料損毀,建議您重新建立含有損毀 VM 執行個體的節點集區,藉此復原中繼資料。您必須在叢集中新增節點集區,並增加新節點集區的節點數量,同時限制並移除其他節點集區的節點。請參閱這篇文章中的指示,瞭解如何遷移節點集區之間的工作負載。
如要查看執行個體中繼資料的編輯者和編輯時間,您可以查看 Compute Engine 稽核記錄資訊,或使用 Logs Explorer 搭配類似下列的搜尋查詢來尋找記錄:
resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"
您可以在記錄中找到要求發送者的 IP 位址和使用者代理程式。例如:
requestMetadata: {
callerIp: "REDACTED"
callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}
在節點集區之間遷移工作負載
請按照下列操作說明,將工作負載從一個節點集區遷移至另一個節點集區。如要變更節點集區中節點的機器屬性,請參閱「變更節點機器屬性以垂直調整資源配置」。
瞭解如何將 Pod 遷移至新的節點集區
如要將 Pod 遷移至新的節點集區,請完成下列步驟:
隔離現有節點集區中的節點:這項作業會將現有節點集區中的節點標示為「無法排程」。這樣一來,Kubernetes 就會停止將新 Pod 安排至這些節點。
清空現有節點集區中的節點:按程序清空在現有節點集區的節點上執行的工作負載。
針對每個節點個別執行這些步驟,會導致現有節點集區中執行的 Pod 正常終止。Kubernetes 會將這些 Pod 重新排程至其他可用節點。
為確保 Kubernetes 正常終止應用程式,容器應處理 SIGTERM 信號。使用這種方法可關閉與用戶端的有效連線,並以乾淨的方式提交或回溯資料庫交易。在 Pod 資訊清單中,您可以使用 spec.terminationGracePeriodSeconds 欄位,指定 Kubernetes 必須等待多久,才能停止 Pod 中的容器。預設值為 30 秒。
如要進一步瞭解 Pod 終止,請參閱 Kubernetes 說明文件。
您可以使用 kubectl cordon 和 kubectl drain 指令,封鎖並排空節點。
建立節點集區並遷移工作負載
如要將工作負載遷移至新的節點集區,請建立新的節點集區,然後限制並排除現有節點集區中的節點:
在叢集中新增節點集區。
執行下列指令,確認新的節點集區已建立:
gcloud container node-pools list --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION更改下列內容:
CLUSTER_NAME:叢集名稱。CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。如果是區域叢集,請提供區域;如果是可用區叢集,請提供可用區。
如要停用現有節點集區的自動調度資源功能 (如果已啟用),請執行下列指令:
gcloud container clusters update CLUSTER_NAME --location=CONTROL_PLANE_LOCATION \ --no-enable-autoscaling \ --node-pool=EXISTING_NODE_POOL_NAME執行下列指令,查看 Pod 執行的節點 (請參閱「
NODE」欄):kubectl get pods -o=wide取得現有節點集區中的節點清單,並將
EXISTING_NODE_POOL_NAME替換為名稱:kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME執行
kubectl cordon NODE指令 (將NODE替換為前一指令中的名稱)。下列 Shell 指令會逐一查看現有節點集區中的每個節點,並將其標示為「無法排程」:for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl cordon "$node"; done您可以視需要更新現有節點集區上執行的工作負載,為標籤
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME新增 nodeSelector,其中NEW_NODE_POOL_NAME是新節點集區的名稱。這有助於確保 GKE 將這些工作負載放置在新節點集區的節點上。逐一清空節點,方法是逐出所有 Pod,並分配 10 秒的優雅終止期:
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl drain --force --ignore-daemonsets --delete-emptydir-data --grace-period=GRACEFUL_TERMINATION_SECONDS "$node"; done將
GRACEFUL_TERMINATION_PERIOD_SECONDS替換為正常終止所需的時間。執行下列指令,確認現有節點集區中的節點在節點清單中是否處於
SchedulingDisabled狀態:kubectl get nodes此外,您應該會看到 Pod 現在在新節點集區的節點上運作:
kubectl get pods -o=wide如不需要現有節點集區,請刪除:
gcloud container node-pools delete default-pool --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
後續步驟
如果說明文件無法解決您的問題,請參閱「取得支援」一文,瞭解如何取得進一步協助,包括下列主題的建議:
- 與 Cloud Customer Care 聯絡,建立客服案件。
- 在 StackOverflow 提問,並使用
google-kubernetes-engine標記搜尋類似問題,向社群尋求支援。你也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開 Issue Tracker 開啟問題或功能要求。