Google Kubernetes Engine (GKE) 叢集的儲存空間問題可能以各種形式呈現,包括效能瓶頸、磁碟區掛接失敗,以及使用特定磁碟類型搭配特定機型時發生錯誤。這些問題可能會影響應用程式的狀態、資料持續性,以及整體工作負載的健康狀態。
本文說明如何解決叢集儲存功能常見問題。瞭解如何排解磁碟區佈建和附加、資料存取和效能,以及儲存空間容量管理相關問題。
這項資訊對平台管理員和管理叢集基礎架構與儲存空間的運算子,以及工作負載依賴永久儲存空間的應用程式開發人員而言,都非常重要。如要進一步瞭解內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。 Google Cloud
錯誤 400:無法將 RePD 附加至最佳化 VM
地區永久磁碟無法搭配記憶體最佳化機器或運算最佳化機器使用。
如果不是非得使用地區永久磁碟,建議考慮使用非地區永久磁碟儲存空間類別。如果必須使用地區永久磁碟,請考慮使用節點 taint 和容許條件等排程策略,確保需要地區永久磁碟的 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 Storage Pool 中,將 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 客戶服務聯絡,建立支援案件。
- 在 StackOverflow 上提問,並使用
google-kubernetes-engine標記搜尋類似問題,從社群取得支援。你也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開版 Issue Tracker 開啟錯誤或功能要求。