Google Kubernetes Engine (GKE) 叢集的儲存空間問題可能以多種方式呈現,包括效能瓶頸、磁碟區掛接失敗,以及特定磁碟類型與特定機器類型搭配使用時發生錯誤。這些問題可能會影響應用程式狀態、資料持久性和整體工作負載健康狀態。
請參閱這份文件,解決影響叢集儲存空間功能的常見問題。瞭解如何排解磁碟區佈建和連結、資料存取和效能,以及儲存空間容量管理等相關問題。
對於管理叢集基礎架構和儲存空間的平台管理員和操作員,以及工作負載仰賴永久儲存空間的應用程式開發人員,這項資訊都非常重要。如要進一步瞭解 Cloud de Confiance by S3NS 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。
錯誤 400:無法將 RePD 附加至最佳化 VM
區域永久磁碟限制搭配記憶體最佳化機器或運算最佳化機器使用。
如果並非一定要使用區域性永久磁碟,建議您使用非區域性永久磁碟儲存空間類別。如果必須使用區域性永久磁碟,請考慮採用污點和容忍等排程策略,確保需要區域性永久磁碟的 Pod 排定在非最佳化機器的節點集區中。
排解磁碟效能問題
開機磁碟的效能很重要,因為 GKE 節點的開機磁碟不僅用於作業系統,還用於下列用途:
- Docker 映像檔。
- 未掛接為磁碟區的容器檔案系統 (即疊加檔案系統),通常包含
/tmp等目錄。 - 磁碟支援的
emptyDir磁碟區,除非節點使用本機 SSD。
節點上所有相同磁碟類型的磁碟會共用磁碟效能。舉例來說,如果您有 100 GB 的 pd-standard 開機磁碟,以及 100 GB 的 pd-standard PersistentVolume,且活動量很大,則開機磁碟的效能會與 200 GB 的磁碟相同。此外,如果 PersistentVolume 上有大量活動,也會影響開機磁碟的效能。
如果節點上出現類似下列訊息,可能表示磁碟效能偏低:
INFO: task dockerd:2314 blocked for more than 300 seconds.
fs: disk usage and inodes count on following dirs took 13.572074343s
PLEG is not healthy: pleg was last seen active 6m46.842473987s ago; threshold is 3m0s
為解決這類問題,請參閱下列說明:
- 請務必參閱儲存磁碟類型比較,並選擇符合需求的永久磁碟類型。
- 如果節點使用大小不到 200 GB 的標準永久磁碟,就常會發生這個問題。建議您增加磁碟大小或改用 SSD,尤其是用於正式環境的叢集。
- 建議您為節點集區的臨時儲存空間啟用本機 SSD。如果容器經常使用
emptyDir磁碟區,這種做法特別有效。
由於 fsGroup 設定,掛接磁碟區停止回應
如果 Pod 設有 fsGroup 設定,可能會導致 PersistentVolume 掛接失敗。一般來說,掛接作業會自動重試,並自行解決掛接失敗的問題。不過,如果 PersistentVolume 含有大量檔案,kubelet 會嘗試變更檔案系統中每個檔案的擁有權,這可能會增加磁碟區掛接延遲時間。
Unable to attach or mount volumes for pod; skipping pod ... timed out waiting for the condition
如要確認掛接失敗錯誤是否由 fsGroup 設定造成,請查看 Pod 的記錄。如果問題與 fsGroup 設定有關,您會看到下列記錄項目:
Setting volume ownership for /var/lib/kubelet/pods/POD_UUID and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699
如果 PersistentVolume 在幾分鐘內未掛接,請嘗試下列步驟來解決問題:
- 減少磁碟區中的檔案數量。
- 停止使用
[fsGroup]設定。 - 將應用程式
fsGroupChangePolicy變更為OnRootMismatch。
磁碟作業速度緩慢,導致 Pod 建立失敗
詳情請參閱 containerd 問題 #4604。
受影響的 GKE 節點版本:1.18、1.19、1.20.0 至 1.20.15-gke.2100、1.21.0 至 1.21.9-gke.2000、1.21.10 至 1.21.10-gke.100、1.22.0 至 1.22.6-gke.2000、1.22.7 至 1.22.7-gke.100、1.23.0 至 1.23.3-gke.700、1.23.4 至 1.23.4-gke.100
k8s_node container-runtime 記錄中可能會顯示下列錯誤範例:
Error: failed to reserve container name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0": name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0" is reserved for "1234567812345678123456781234567812345678123456781234567812345678"
緩解措施
- 如果 Pod 失敗,請考慮在 PodSpec 中使用
restartPolicy:Always或restartPolicy:OnFailure。 - 提高開機磁碟 IOPS (例如升級磁碟類型或增加磁碟大小)。
修正
這個問題已在 containerd 1.6.0 以上版本中修正。包含這項修正的 GKE 版本為 1.20.15-gke.2100 以上版本、1.21.9-gke.2000 以上版本、1.21.10-gke.100 以上版本、1.22.6-gke.2000 以上版本、1.22.7-gke.100 以上版本、1.23.3-gke.1700 以上版本和 1.23.4-gke.100 以上版本
磁碟區擴充變更未反映在容器檔案系統中
執行磁碟區擴充時,請務必更新 PersistentVolumeClaim。直接變更 PersistentVolume 可能導致磁碟區無法擴充。這可能導致下列其中一種情況:
如果直接修改 PersistentVolume 物件,PersistentVolume 和 PersistentVolumeClaim 值都會更新為新值,但檔案系統大小不會反映在容器中,且仍會使用舊的磁碟區大小。
如果直接修改 PersistentVolume 物件,然後更新 PersistentVolumeClaim,將
status.capacity欄位更新為新的大小,可能會導致 PersistentVolume 變更,但 PersistentVolumeClaim 或容器檔案系統不會變更。
如要解決這個問題,請完成下列步驟:
- 保留修改後的 PersistentVolume 物件。
- 編輯 PersistentVolumeClaim 物件,並將
spec.resources.requests.storage設為高於 PersistentVolume 中使用的值。 - 確認 PersistentVolume 已調整為新大小。
完成這些變更後,kubelet 應會自動調整 PersistentVolume、PersistentVolumeClaim 和容器檔案系統的大小。
確認變更是否反映在 Pod 中。
kubectl exec POD_NAME -- /bin/bash -c "df -h"
將 POD_NAME 替換為附加至 PersistentVolumeClaim 的 Pod。
所選機型應具備本機 SSD
建立使用本機 SSD 的叢集或節點集區時,可能會遇到下列錯誤:
The selected machine type (c3-standard-22-lssd) has a fixed number of local SSD(s): 4. The EphemeralStorageLocalSsdConfig's count field should be left unset or set to 4, but was set to 1.
在錯誤訊息中,您可能會看到 LocalNvmeSsdBlockConfig,而非 EphemeralStorageLocalSsdConfig,具體取決於您指定的內容。
如果指定的本機 SSD 磁碟數量與機器類型包含的本機 SSD 磁碟數量不符,就會發生這項錯誤。
如要解決這個問題,請指定與所需機器類型相符的本機 SSD 磁碟數量。如果是第三代機器系列,您必須省略本機 SSD count 旗標,系統會自動設定正確的值。
Hyperdisk 儲存空間集區:無法建立叢集或節點集區
在Hyperdisk 儲存空間集區中,嘗試佈建 Hyperdisk Balanced 磁碟做為節點的開機磁碟或附加磁碟時,可能會遇到 ZONE_RESOURCE_POOL_EXHAUSTED 錯誤或類似的 Compute Engine 資源錯誤。
當您嘗試在資源不足的可用區中建立 GKE 叢集或節點集區時,就會發生這種情況,例如:
- 該可用區可能沒有足夠的 Hyperdisk Balanced 磁碟。
- 可用區可能沒有足夠容量,無法建立您指定機型的節點,例如
c3-standard-4。
如何解決這個問題:
- 請在相同區域內選取新的可用區,該可用區必須有足夠容量,可容納所選機型,且支援 Hyperdisk Balanced 儲存空間集區。
- 刪除現有的儲存空間集區,並在新可用區中重新建立。這是因為儲存空間集區是可用區資源。
- 在新的可用區建立叢集或節點集區。
偵測到節點儲存空間壓力偏高
如果發現與 StoragePressureRootFileSystem 相關的節點事件或條件,且原因為 StoragePressureDetected,表示節點的根檔案系統或重要儲存空間掛接點的磁碟用量偏高,接近容量上限。
使用 kubectl describe node NODE_NAME 指令描述節點時,可能會看到類似以下的事件:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Warning StoragePressureDetected 46m device-capacity-monitor Node condition StoragePressureRootFileSystem is now: True, reason: StoragePressureDetected, message: "Disk /dev/nvme0n1 usage 89% exceeds threshold 85%"
原因:
StoragePressureDetected 原因表示節點根檔案系統 (通常是 mnt/stateful_partition 或相關掛接) 的磁碟用量已超過預先定義的門檻 (例如 85%)。可能原因如下:
- 工作負載將過多資料寫入非本機 SSD 支援的 emptyDir 磁碟區。
- 大型容器映像檔正在提取至節點。
- 記錄檔在節點上累積。
- 其他程序占用磁碟空間。
如果磁碟用量持續偏高,可能會導致節點不穩定、Pod 遭淘汰和應用程式故障。
偵錯與解決:
找出磁碟用量:使用 SSH 連線至受影響的節點,並使用 df -h 等指令檢查各個掛接點的磁碟用量,特別注意 /mnt/stateful_partition 和任何臨時儲存空間掛接點。
分析工作負載儲存空間模式:查看節點上執行的 Pod 儲存空間要求和使用模式。找出是否有特定工作負載耗用過多臨時儲存空間。
增加節點儲存空間容量:請注意,主要解決方法通常是確保節點有足夠的儲存空間容量,可處理工作負載。請考量下列事項:
- 使用較大的開機磁碟:建立節點集區時,如果工作負載需要根檔案系統提供更多臨時儲存空間,請選取較大的開機磁碟。
- 使用較大的本機 SSD 做為臨時儲存空間:如果工作負載需要高效能、低延遲的臨時儲存空間,請將節點集區設為使用本機 SSD。這會為 emptyDir 磁碟區提供獨立且更大的容量。
- 調整工作負載要求或限制:確認 Pod 規格包含適當的臨時儲存空間要求和限制,協助排程器將 Pod 放在空間充足的節點上,並防止磁碟用量失控。
- 清理未使用的資源:如果磁碟用量過高,請從節點中移除任何不必要的檔案、舊容器映像檔或記錄。
只要解決節點的儲存空間容量和用量問題,就能減少與 StoragePressureDetected 相關的問題,並協助節點運作。
排解 Cloud Storage FUSE 記憶體不足 (OOM) 事件
如果 Pod 記憶體使用率偏高,或發生與 Cloud Storage FUSE CSI 驅動程式相關的記憶體不足 (OOM) 事件,您可以使用 Cloud Profiler 收集及分析 CPU 和記憶體快照。如要設定這些選項,請參閱「設定 Cloud Storage FUSE CSI 驅動程式邊車容器」。
當 Pod 發生 OOM 終止事件時,您可以使用下列工作流程,將事件與正確的 Cloud Profiler 快照建立關聯:
- 查看 Cloud Logging:前往 Cloud Logging,找出 Kubernetes OOM 事件。
依 Pod 名稱篩選:執行下列查詢,找出特定 Pod 的事件記錄,並將
POD_NAME替換為工作負載 Pod 的名稱:jsonPayload.involvedObject.name="POD_NAME" jsonPayload.involvedObject.kind="Pod" OOMKilled擷取 Pod UID:展開相關的 OOM 事件記錄,並記下時間戳記和
jsonPayload.involvedObject.uid處的確切 Pod UID。在 Cloud Profiler 中分析:前往 Cloud Profiler,使用
POD_NAME_POD_UID格式篩選「服務版本」,並調整日期範圍,使其與 OOM 時間戳記相符。這樣一來,您就能確保查看的是特定容器執行個體在終止前的確切記憶體設定檔。
運算能力不足,導致有狀態工作負載卡在Pending狀態
如果您的有狀態工作負載卡在 Pending 狀態,並顯示 ZONE_RESOURCE_POOL_EXHAUSTED 或 GCE_STOCKOUT 等錯誤訊息,則特定可用區的運算能力可能有限。
如果運算節點在容量不足的可用區中離線,可能無法更換該節點。如果 Stateful Pod 依賴預先存在的可用區 PersistentVolume (例如標準 pd-ssd 或 pd-balanced 磁碟),則只能在建立該磁碟區的可用區中使用。由於 Pod 必須在該特定可用區中排定,才能掛接磁碟區,因此 Pod 會維持 Pending 狀態,直到該可用區的運算容量可用為止。
為避免日後發生這個問題,請考慮採取下列措施:
- 避免在
pd-ssd和pd-balanced之間進行同可用區備用:pd-ssd和pd-balanced磁碟區共用可用區中的相同容量限制和可用性集區,因此在「相同」可用區中將 StorageClass 從pd-ssd變更為pd-balanced,無法解決容量不足的問題。請勿嘗試將此做為備用方案。 - 使用與 Hyperdisk 相容的機型:部分機器系列支援 Hyperdisk。建議使用與 Hyperdisk 相容的機型,因為這類機型可能有不同的可用性限制,有助於解決可用區容量不足的問題。遷移工作負載前,請確認您有足夠的磁碟配額。
- 啟用動態拓撲繫結 (
WaitForFirstConsumer):建立新的有狀態工作負載時,請使用volumeBindingMode: WaitForFirstConsumer欄位值組合設定 StorageClass 定義。這項設定會延遲建立磁碟區,直到 Pod 排定至可用區中運算能力充足的健康節點,有助於防止過早建立磁碟區,導致 Pod 鎖定在離線或資源耗盡的可用區。 - 設定 VM 備用方案的自動磁碟類型選取功能:在 GKE 1.35.3-gke.1290000 以上版本中,您可以為跨 VM 世代 (例如 N4 到 N2,或 C4 到 C2) 備用的工作負載設定自訂 ComputeClass。使用自動選取磁碟類型功能,即可透過
parameters.type: dynamic和use-allowed-disk-topology: "true"欄位值組合設定StorageClass定義。這項設定可讓 GKE 在較新的機器世代上自動佈建hyperdisk-balanced磁碟,並在較舊的世代上改用pd-balanced磁碟。
後續步驟
如果說明文件無法解決您的問題,請參閱「取得支援」一文,進一步瞭解如何取得協助,包括下列主題的建議:
- 與 Cloud Customer Care 聯絡,建立客服案件。
- 在 StackOverflow 提問,並使用
google-kubernetes-engine標記搜尋類似問題,向社群尋求支援。您也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開 Issue Tracker 提出問題或功能要求。