Google Kubernetes Engine (GKE) Autopilot 叢集的問題可能會影響應用程式的可用性和作業效率。這些問題可能會中斷應用程式的整個生命週期,從初始部署到負載下的資源調度都可能受到影響。
您可以在這個頁面診斷及解決 Autopilot 叢集的常見問題。瞭解如何排解叢集建立問題 (防止叢集佈建)、資源調度問題 (例如 out
of resources 錯誤),以及工作負載專屬問題 (例如臨時儲存空間錯誤或 Pod 卡在 Pending 狀態)。
這項資訊對於應用程式開發人員來說非常重要,因為他們需要確保應用程式能順利部署及執行;對於平台管理員和營運人員來說也很重要,因為他們負責 Autopilot 叢集的整體健康狀態和資源管理。如要進一步瞭解 Google Cloud 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。
叢集問題
無法建立叢集:已註冊 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.setCommonInstanceMetadataIAM 權限,才能執行這項操作。
節點無法向上擴充:Compute Engine 資源不足
如果工作負載要求的資源量超過 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 運算資源預留項目與
PerformanceComputeClass 或加速 Pod。詳情請參閱「耗用預留的可用區資源」。
節點無法擴充資源:Pod 可用區資源超出上限
如果新節點會違反資源限制,Autopilot 就不會為特定可用區中的 Pod 佈建新節點,進而導致下列問題。
記錄中的錯誤訊息大致如下:
"napFailureReasons": [
{
"messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
...
這項錯誤是指noScaleUp事件,其中自動佈建節點功能並未針對可用區內的 Pod 佈建任何節點群組。
如果遇到這項錯誤,請確認下列事項:
- Pod 有足夠的記憶體和 CPU。
- Pod IP 位址 CIDR 範圍夠大,可支援預期的叢集大小上限。
工作負載排定在舊版機器系列上執行,或因儲存空間不相容而處於 Pending 狀態
如果有狀態工作負載使用較早的 Persistent Disk 磁碟區類型,例如標準永久磁碟 (pd-standard) 或 SSD 永久磁碟 (pd-ssd) 磁碟區,就會發生這個問題。這些磁碟區類型與 C3 或 E4 等較新的機器系列不相容。
這個問題會以以下兩種方式呈現:
- 症狀 1:您預期在較新的一般用途機器系列 (例如 C3) 上執行的工作負載,卻自動排定在 E2 節點上。
- 徵兆 2:明確要求較新機器系列的 Pod (例如使用
nodeSelector欄位或自訂 ComputeClass) 仍處於Pending狀態。
根本原因
GKE Autopilot 會強制執行所要求儲存空間類型與節點機器系列的相容性。較新的機器系列 (例如 C3 和 E4) 需要 Google Cloud Hyperdisk 儲存空間 (例如 hyperdisk-balanced 磁碟類型)。這些機器系列不支援較早的永久磁碟磁碟區類型,例如標準永久磁碟 (pd-standard) 或 SSD 永久磁碟 (pd-ssd) 磁碟區。
- 如果未指定機器系列,GKE Autopilot 會自動將工作負載排程至 E2 節點,因為 E2 節點支援這些永久磁碟磁碟區類型。工作負載會自動從預設的新硬體改回舊硬體。
- 如果您明確要求使用較新的機器系列 (例如 C3 或 E4),但附加較早的永久磁碟區類型 (例如標準永久磁碟 (
pd-standard) 或 SSD 永久磁碟 (pd-ssd) 磁碟區),GKE Autopilot 就無法同時滿足這兩項要求。Pod 會卡在Pending狀態。
驗證
如要確認工作負載是否受到這項相容性限制影響,請執行下列步驟:
- 檢查 Pod 的磁碟區設定,確認是否使用較舊的 Persistent Disk 磁碟區類型,例如標準永久磁碟 (
pd-standard) 或 SSD 永久磁碟 (pd-ssd) 磁碟區。 如果 Pod 停滯在
Pending狀態,請檢查叢集自動配置器可視性記錄。尋找節點自動佈建 (NAP) 評估記錄,類似於下列內容:NAP: injected node groups for requirements...檢查
families="..."清單的記錄訊息,檢查清單中是否缺少較新的機器系列 (例如e4或c3ID)。如果缺少 ID,表示 GKE 在排程期間因儲存空間需求而篩除這些家庭。e4ID 用於 E4 機器系列的內部記錄。
解析度
如要解決這個問題,請採取下列任一做法:
- 使用 Hyperdisk 儲存空間:更新
StorageClass或磁碟區定義,改用與新版機器系列相容的 Google Cloud Hyperdisk 儲存空間 (例如hyperdisk-balanced磁碟類型)。 - 允許在舊版系列上排程:如要使用較舊的 Persistent Disk 磁碟區類型 (例如標準永久磁碟 (
pd-standard) 或 SSD 永久磁碟 (pd-ssd) 磁碟區),請移除對較新機器系列的任何明確要求 (例如nodeSelector欄位或自訂 ComputeClass)。移除這些要求後,GKE Autopilot 就能在 E2 等相容節點上排定 Pod。
工作負載問題
工作負載因臨時儲存空間錯誤而卡住
如果 Pod 暫時性儲存空間要求超過 GKE 1.28.6-gke.1317000 以上版本 Autopilot 的 10GiB 上限,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:
# This section drops NET_RAW to mitigate security vulnerabilities
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
由於 NRI RunPodSandbox 失敗,Pod 無法在節點上執行
在極少數情況下,預設、Balanced、Scale-Out、autopilot 和 autopilot-spot 運算類別中的 Autopilot 節點可能會進入某種狀態,導致系統 Pod (例如 anetd) 和指派給該節點的使用者 Pod 無法轉換為執行中狀態。如果 anetd 無法轉換為執行中狀態,表示節點上的 Pod 網路部分或完全中斷。只有在特定叢集控制層升級期間,才會觸發這個錯誤狀態。
如果發現這個問題,可以按照緩解特定節點上不可靠的工作負載效能程序,在特定節點上緩解這個問題。
為避免問題再次發生,請手動將叢集升級至下列任一 GKE 修補程式版本:
- 1.35:所有修補程式版本
- 1.34:1.34.1-gke.3899000 以上版本
- 1.33:1.33.5-gke.2392000 以上版本
如果懷疑節點處於這項錯誤狀態,請按照下列步驟確認:
找出在疑似有問題的節點上執行的
efficiency-daemonPod:DAEMON_POD_NAME=$(kubectl get pods \ --namespace kube-system \ --selector k8s-app=efficiency-daemon \ --field-selector spec.nodeName=NODE_NAME \ --output custom-columns=":metadata.name" \ --no-headers) echo $DAEMON_POD_NAME如果節點上沒有
efficiency-daemonPod,表示節點不受這個特定問題影響。檢查
efficiency-daemonPod 是否有特定錯誤:kubectl logs -n kube-system $DAEMON_POD_NAME | grep "connect: operation not permitted" | wc -l如果輸出內容大於
10,節點很可能受到這個問題影響。
如果指派給節點的 Pod 持續在 Pod 事件中顯示下列錯誤訊息,表示節點受到這個問題影響:Failed to create pod sandbox: rpc error: code = Unknown desc = NRI RunPodSandbox failed: rpc error: code = Unknown desc = internal error: reconciliation failed。
後續步驟
如果無法在文件中找到問題的解決方案,請參閱「取得支援」一文,取得進一步協助,包括下列主題的建議:
- 向 Cloud Customer Care 團隊申請開立支援案件。
- 在 StackOverflow 提問,並使用
google-kubernetes-engine標記搜尋類似問題,向社群尋求支援。你也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開 Issue Tracker 提出問題或功能要求。