本頁面說明如何解決 Google Kubernetes Engine (GKE) Autopilot 叢集的問題。
叢集問題
無法建立叢集:已註冊 0 個節點
如果您嘗試使用已停用或沒有必要權限的 IAM 服務帳戶建立 Autopilot 叢集,就會發生下列問題。建立叢集失敗,並顯示下列錯誤訊息:
All cluster resources were brought up, but: only 0 nodes out of 2 have registered.
如要解決這個問題,請按照下列步驟操作:
檢查預設 Compute Engine 服務帳戶或要使用的自訂 IAM 服務帳戶是否已停用:
gcloud iam service-accounts describe SERVICE_ACCOUNT
將
SERVICE_ACCOUNT
替換為服務帳戶電子郵件地址,例如my-iam-account@my-first-project.iam.gserviceaccount.com
。如果服務帳戶已停用,輸出結果會與下列內容相似:
disabled: true displayName: my-service-account email: my-service-account@my-project.iam.gserviceaccount.com ...
如果服務帳戶已停用,請啟用:
gcloud iam service-accounts enable SERVICE_ACCOUNT
如果服務帳戶已啟用,但錯誤仍未解決,請授予服務帳戶 GKE 所需的最低權限:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:SERVICE_ACCOUNT" \
--role roles/container.defaultNodeServiceAccount
叢集有 0 個節點時,命名空間會卡在 Terminating 狀態
如果叢集縮減至零個節點,然後您刪除叢集中的命名空間,就會發生下列問題。metrics-server
元件無法接受命名空間刪除要求,因為該元件沒有任何副本。
如要診斷這個問題,請執行下列指令:
kubectl describe ns/NAMESPACE_NAME
將 NAMESPACE_NAME
替換為命名空間的名稱。
輸出內容如下:
Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request
如要解決這個問題,請調高任何工作負載的規模,觸發 GKE 建立新節點。節點準備就緒後,系統就會自動完成命名空間刪除要求。GKE 刪除命名空間後,請將工作負載縮減。
資源調度問題
節點向上擴充作業失敗:Pod 可能無法排定
如果Google Cloud 專案中停用了序列埠記錄功能,就會發生下列問題。GKE Autopilot 叢集需要序列埠記錄功能,才能有效偵錯節點問題。如果停用序列埠記錄功能,Autopilot 就無法佈建節點來執行工作負載。
Kubernetes 事件記錄中的錯誤訊息類似於下列內容:
LAST SEEN TYPE REASON OBJECT MESSAGE
12s Warning FailedScaleUp pod/pod-test-5b97f7c978-h9lvl Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled
機構政策可能會強制執行 compute.disableSerialPortLogging
限制,在機構層級停用序列埠記錄。您也可以在專案或虛擬機器 (VM) 執行個體層級停用序列埠記錄功能。
如要解決這個問題,請按照下列步驟操作:
- 請 Google Cloud 機構政策管理員移除含有 Autopilot 叢集的專案中的
compute.disableSerialPortLogging
限制。 - 如果沒有強制執行這項限制的機構政策,請嘗試在專案中繼資料中啟用序列埠記錄功能。執行這項操作需要
compute.projects.setCommonInstanceMetadata
IAM 權限。
節點向上擴充失敗:GCE 資源不足
當工作負載要求的資源超出 Compute Engine 區域或可用區的可用資源時,就會發生下列問題。Pod 可能會維持在 Pending
狀態。
檢查 Pod 事件:
kubectl events --for='pod/POD_NAME' --types=Warning
將
RESOURCE_NAME
替換為待處理的 Kubernetes 資源名稱。例如pod/example-pod
。輸出結果會與下列內容相似:
LAST SEEN TYPE REASON OBJECT Message 19m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 14m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 12m (x2 over 18m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled. 34s (x3 over 17m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
如要解決這個問題,請嘗試下列方法:
- 在其他區域或可用區部署 Pod。如果 Pod 有區域限制 (例如拓撲選取器),請盡可能移除限制。如需操作說明,請參閱「將 GKE Pod 放置在特定區域」。
- 在其他區域建立叢集,然後重試部署作業。
- 請改用其他運算類別。如果運算類別採用較小的 Compute Engine 機器類型,就越有可能提供可用資源。舉例來說,Autopilot 的預設機器類型具有最高可用性。如需運算類別和對應機器類型的清單,請參閱「何時使用特定運算類別」。
- 如果您執行 GPU 工作負載,要求使用的 GPU 可能無法在節點位置使用。請嘗試在其他位置部署工作負載,或要求使用其他類型的 GPU。
為避免日後因資源可用性而導致擴充問題,請考慮採取下列方法:
- 使用 Kubernetes PriorityClasses,在叢集中持續佈建額外的運算容量。詳情請參閱「為快速 Pod 擴展作業佈建額外的運算容量」。
- 搭配使用 Compute Engine 容量預留功能與 Performance 或 Accelerator 計算類別。詳情請參閱「耗用可用區保留資源」。
節點無法向上擴充:Pod 超出可用區資源
如果新節點會違反資源限制,Autopilot 就不會為特定可用區中的 Pod 佈建新節點,因此會發生下列問題。
記錄中的錯誤訊息類似於下列內容:
"napFailureReasons": [
{
"messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
...
這項錯誤是指noScaleUp
事件,其中節點自動佈建功能並未在可用區中為 Pod 佈建任何節點群組。
如果遇到這項錯誤,請確認下列事項:
- Pod 具有充足的記憶體和 CPU。
- Pod IP 位址 CIDR 範圍夠大,可支援預期的叢集大小上限。
工作負載問題
工作負載卡住,並顯示暫時儲存空間錯誤
如果 Pod 暫時性儲存空間要求超過 GKE 1.28.6-gke.1317000 以上版本 Autopilot 的上限 10 GiB,GKE 就不會建立 Pod。
如要診斷這個問題,請說明工作負載控制器,例如 Deployment 或 Job:
kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME
更改下列內容:
CONTROLLER_TYPE
:工作負載控制器類型,例如replicaset
或daemonset
。如需控制器類型清單,請參閱工作負載管理。CONTROLLER_NAME
:停滯的工作負載名稱。
如果 Pod 因臨時儲存空間要求超出上限而未建立,輸出內容會類似於以下內容:
# lines omitted for clarity
Events:
{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}
如要解決這個問題,請更新暫時性儲存空間要求,確保工作負載容器和 Webhook 插入的容器所要求的暫時性儲存空間總量,小於或等於允許上限。如要進一步瞭解上限,請參閱「Autopilot 中的資源要求」一文,瞭解工作負載設定。
Pod 停滯在「Pending」狀態
如果您選取要讓 Pod 使用的特定節點,但 Pod 和必須在節點上執行的 DaemonSet 中的資源要求總和,超出節點可分配的最大容量,Pod 可能會卡在 Pending
狀態。這可能會導致 Pod 進入 Pending
狀態,並維持未排程狀態。
為避免發生這個問題,請評估已部署工作負載的大小,確保工作負載符合 Autopilot 資源要求上限。
您也可以嘗試先排定 DaemonSet,再排定一般工作負載 Pod。
特定節點上的工作負載效能持續不穩定
在 GKE 1.24 以上版本中,如果特定節點上的工作負載持續發生中斷、當機或類似的不可靠行為,您可以使用下列指令封鎖節點,向 GKE 回報問題節點:
kubectl drain NODE_NAME --ignore-daemonsets
將 NODE_NAME
替換為有問題的節點名稱。您可以執行 kubectl get nodes
找出節點名稱。
GKE 會執行下列操作:
- 從節點中清空現有工作負載,並停止在該節點上排定工作負載。
- 自動在其他節點上,重新建立由控制器 (例如 Deployment 或 StatefulSet) 管理的任何遭逐出工作負載。
- 終止節點上剩餘的任何工作負載,並在一段時間後修復或重新建立節點。
- 如果您使用 Autopilot,GKE 會立即關閉並取代節點,且忽略任何已設定的 PodDisruptionBudget。
Pod 在空白叢集上排程的時間超出預期
當您將工作負載部署至沒有其他工作負載的 Autopilot 叢集時,就會發生這個事件。Autopilot 叢集一開始沒有可用節點,如果叢集為空,系統會將節點數量縮減至零,避免叢集出現未使用的運算資源。在沒有節點的叢集中部署工作負載,會觸發擴充事件。
如果發生這種情況,表示 Autopilot 運作正常,您不需採取任何行動。新節點啟動後,工作負載就會如預期部署。
檢查 Pod 是否在等待新節點:
描述待處理的 Pod:
kubectl describe pod POD_NAME
將
POD_NAME
替換為待處理 Pod 的名稱。請檢查輸出內容的
Events
區段。如果 Pod 正在等待新節點,輸出內容會類似如下:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 11s gke.io/optimize-utilization-scheduler no nodes available to schedule pods Normal TriggeredScaleUp 4s cluster-autoscaler pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
TriggeredScaleUp
事件表示叢集正在從零個節點擴充,擴充至執行已部署工作負載所需的節點數量。
系統 Pod 無法在空白叢集上排定時間
當叢集中沒有任何您自己的工作負載執行時,就會發生這個事件,導致叢集縮減至零個節點。Autopilot 叢集一開始不會有可用節點,如果叢集未執行任何工作負載,就會縮減至零個節點。這項行為可盡量減少叢集中浪費的運算資源。
當叢集縮減至零個節點時,GKE 系統工作負載不會排程,且會維持在 Pending
狀態。這是預期行為,不必採取任何行動。下次將工作負載部署至叢集時,GKE 會擴充叢集,待處理的系統 Pod 將在這些節點上執行。
如要檢查系統 Pod 是否因叢集空白而處於待處理狀態,請執行下列操作:
檢查叢集是否有任何節點:
kubectl get nodes
輸出內容如下,表示叢集有零個節點:
No resources found
檢查系統 Pod 的狀態:
kubectl get pods --namespace=kube-system
輸出結果會與下列內容相似:
NAME READY STATUS RESTARTS AGE antrea-controller-horizontal-autoscaler-6d97f7cf7c-ngfd2 0/1 Pending 0 9d egress-nat-controller-84bc985778-6jcwl 0/1 Pending 0 9d event-exporter-gke-5c5b457d58-7njv7 0/2 Pending 0 3d5h event-exporter-gke-6cd5c599c6-bn665 0/2 Pending 0 9d konnectivity-agent-694b68fb7f-gws8j 0/2 Pending 0 3d5h konnectivity-agent-7d659bf64d-lp4kt 0/2 Pending 0 9d konnectivity-agent-7d659bf64d-rkrw2 0/2 Pending 0 9d konnectivity-agent-autoscaler-5b6ff64fcd-wn7fw 0/1 Pending 0 9d konnectivity-agent-autoscaler-cc5bd5684-tgtwp 0/1 Pending 0 3d5h kube-dns-65ccc769cc-5q5q7 0/5 Pending 0 3d5h kube-dns-7f7cdb9b75-qkq4l 0/5 Pending 0 9d kube-dns-7f7cdb9b75-skrx4 0/5 Pending 0 9d kube-dns-autoscaler-6ffdbff798-vhvkg 0/1 Pending 0 9d kube-dns-autoscaler-8b7698c76-mgcx8 0/1 Pending 0 3d5h l7-default-backend-87b58b54c-x5q7f 0/1 Pending 0 9d metrics-server-v1.31.0-769c5b4896-t5jjr 0/1 Pending 0 9d
檢查系統 Pod 處於
Pending
狀態的原因:kubectl describe pod --namespace=kube-system SYSTEM_POD_NAME
將
SYSTEM_POD_NAME
取代為前一個指令輸出內容中的任何系統 Pod 名稱。輸出結果會與下列內容相似:
... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 4m35s (x27935 over 3d5h) default-scheduler no nodes available to schedule pods ...
在輸出中,
FailedScheduling
事件的Message
欄位中的no nodes available to schedule pods
值表示系統 Pod 未排程,因為叢集是空的。
嘗試從 GKE Autopilot 的 Pod 執行 tcpdump 時,發生與權限相關的錯誤
在 GKE Autopilot 叢集中,禁止存取基礎節點。因此,您必須從 Pod 內執行 tcpdump
公用程式,然後使用 kubectl cp 指令複製該公用程式。
如果您通常從 GKE Autopilot 叢集的 Pod 內執行 tcpdump 公用程式,可能會看到下列錯誤:
tcpdump: eth0: You don't have permission to perform this capture on that device
(socket: Operation not permitted)
這是因為 GKE Autopilot 預設會將安全環境套用至所有 Pod,藉此捨棄 NET_RAW
功能,以降低潛在安全漏洞風險。例如:
apiVersion: v1
kind: Pod
metadata:
labels:
app: tcpdump
name: tcpdump
spec:
containers:
- image: nginx
name: nginx
resources:
limits:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
requests:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
securityContext:
capabilities:
drop:
- NET_RAW
為解決這個問題,如果工作負載需要 NET_RAW
功能,可以重新啟用:
在 Pod 的 YAML 規格的
securityContext
區段中新增NET_RAW
功能:securityContext: capabilities: add: - NET_RAW
在 Pod 中執行
tcpdump
:tcpdump port 53 -w packetcap.pcap tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
使用
kubectl cp
指令將其複製到本機電腦,以進行進一步分析:kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
使用
kubectl exec
執行tcpdump
指令,擷取網路封包並重新導向輸出內容:kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
後續步驟
如果無法在說明文件中找到問題的解決方法,請參閱「取得支援」一文,尋求進一步的協助, 包括下列主題的建議:
- 與 Cloud 客戶服務聯絡,建立支援案件。
- 在 StackOverflow 上提問,並使用
google-kubernetes-engine
標記搜尋類似問題,向社群尋求支援。你也可以加入#kubernetes-engine
Slack 頻道,取得更多社群支援。 - 使用公開問題追蹤工具回報錯誤或提出功能要求。