Kubernetes 中的持久性儲存和 CSI__HTMLTAG_66___
容器是短暫的-當容器重新啟動或 Pod 在另一個節點上重新調度時,內部的所有資料都會遺失。對於資料庫、訊息佇列和檔案儲存等有狀態工作負載來說,這是一個嚴重的問題。 Kubernetes 透過豐富的儲存系統解決了這個問題,從 Kubernetes 1.30-1.31 開始,樹內儲存外掛程式已被完全刪除,取而代之的是 容器儲存介面 (CSI) 標準化驅動程式.
儲存生命週期:從短暫到持久__HTMLTAG_72___
emptyDir:暫時儲存
___HTMLTAG_75__HTMLTAG_76___emptyDir 在 Pod 建立時建立一個空目錄,並在 Pod 的生命週期內持續存在。當Pod被刪除時,資料就完全遺失了。適用於快取、暫存檔案、同一 Pod 中的容器之間共用資料。
程式碼區塊_0
hostPath:節點本地儲存
___HTMLTAG_81__HTMLTAG_82___hostPath 將主機節點上的路徑安裝到容器。容器重啟時資料存在,但當 Pod 調度到其他節點時資料遺失。 不應在生產中使用,除非有特殊原因(系統守護程序、監控代理)。
程式碼區塊_1
PersistentVolume 和 PersistentVolumeClaim
核心概念
Kubernetes 透過兩個抽象化將 提供儲存 (管理員)和 使用儲存 (開發人員)分開:
使用儲存 (開發人員)分開:-
___HTMLTAG_98__HTMLTAG_99___PersistentVolume (PV):由管理員建立或動態配置的叢集級儲存資源。代表一塊實際儲存(NFS共享、雲端磁碟等)
___HTMLTAG_102__HTMLTAG_103___PersistentVolumeClaim (PVC):使用者儲存請求。開發人員只需聲明“我需要 10Gi 的儲存空間並使用 ReadWriteOnce”,而無需知道儲存空間在哪裡。
持久性磁碟區定義
程式碼區塊_2
持久性卷聲明
程式碼區塊_3
程式碼區塊_4
在 Pod 中使用 PVC
程式碼區塊_5
存取模式
Kubernetes 定義了 4 種存取模式,展示如何掛載磁碟區:
-
___HTMLTAG_118__HTMLTAG_119___ReadWriteOnce (RWO):可以掛載讀寫的節點。最常見的是區塊儲存(EBS、GCE PD)。從 K8s 1.22+ 開始,RWO 允許在同一讀寫節點上有多個 Pod。
___HTMLTAG_122__HTMLTAG_123___ReadOnlyMany (ROX):多個節點可以同時以唯讀方式掛載。匹配共享配置/資料。
___HTMLTAG_126__HTMLTAG_127___ReadWriteMany (RWX):許多節點掛載讀寫。需要網路檔案系統,例如 NFS、CephFS、Azure 檔案。重要提示:區塊儲存(EBS、GCE PD)不支援 RWX.
___HTMLTAG_130__HTMLTAG_131___ReadWriteOncePod (RWOP):整個叢集只能掛載一個 Pod。比 RWO 更強——確保 Pod 等級的獨佔訪問,而不僅僅是節點層級。需要 CSI 驅動程式支援。
儲存類別:動態設定
為什麼選擇 StorageClass?
管理員不必手動建立 PV,StorageClass 允許 動態設定 — Kubernetes 在有 PVC 請求時自動建立 PV。管理員只需定義儲存「類別」(例如:ssd-fast、hdd-cheap、nfs-shared)。
程式碼區塊_6
回收政策
-
___HTMLTAG_146__HTMLTAG_147___刪除:刪除PVC時,PV和底層儲存也會被刪除。預設採用動態配置。適合短暫的工作負載。
___HTMLTAG_150__HTMLTAG_151___Retain:當 PVC 被刪除時,PV 被保留(Released 狀態)。管理員必須手動回收。適用於需要資料保護的生產資料庫。
___HTMLTAG_154__HTMLTAG_155___回收:已棄用,不建議。
CSI:容器儲存介面
為什麼樹內插件被刪除?
以前,Kubernetes 有許多樹內儲存外掛程式直接編譯到核心 Kubernetes 二進位(aws-ebs、gce-pd、azure-disk、cephfs、nfs...)。這會產生許多問題:
- 儲存外掛程式中的錯誤可能會導致整個 kube-apiserver/kubelet 崩潰
- 與 Kubernetes 版本相關的儲存驅動程式的發佈週期
- 插件數量增加時難以維護
- 儲存供應商無法獨立發布修復
___HTMLTAG_175__HTMLTAG_176___CSI(容器儲存介面) 透過標準化 Kubernetes 和儲存提供者之間的介面解決了所有這些問題。驅動程式作為單獨的 Pod 運行,可以獨立更新。
時間軸刪除樹內插件__HTMLTAG_180___
___HTMLTAG_182__HTMLTAG_183___K8s 1.26-1.28:許多樹內插件已棄用
___HTMLTAG_186__HTMLTAG_187___K8s 1.29:樹內 NFS 和許多外掛程式已轉換為已棄用,需要 CSI
___HTMLTAG_190__HTMLTAG_191___K8s 1.30:樹內 NFS 外掛程式已刪除
___HTMLTAG_194__HTMLTAG_195___K8s 1.31:樹內 CephFS、Ceph RBD 外掛程式完全刪除__HTMLTAG_197___
___HTMLTAG_198__HTMLTAG_199___K8s 1.32+:繼續刪除剩餘的樹內插件
熱門 CSI 驅動程式
雲端供應商
程式碼區塊_7
Longhorn:開源分散式儲存__HTMLTAG_208___
程式碼區塊_8
程式碼區塊_9
Rook/Ceph:企業儲存
程式碼區塊_10
磁碟區快照
概念__HTMLTAG_214___
磁碟區快照是 K8s 1.20 的 GA 功能,允許建立 PVC 的時間點快照。需要支援快照功能的 CSI 驅動程式並安裝快照控制器。
安裝快照控制器
程式碼區塊_11
VolumeSnapshotClass
程式碼區塊_12
建立磁碟區快照
程式碼區塊_13
程式碼區塊_14
從快照恢復
程式碼區塊_15
程式碼區塊_16
VolumeAttributesClass(K8s 1.29+)
舊方法的問題
以前,如果您想要變更磁碟區的 IOPS 或吞吐量(例如,從 gp3 3000 IOPS 變更為 10000 IOPS),您必須刪除 PVC,建立新的 StorageClass,然後建立新的 PVC — 這是一個複雜且會導致停機的過程。
___HTMLTAG_231__HTMLTAG_232___VolumeAttributesClass (VAC) 是一個新 API (Beta K8s 1.31),允許更改可變卷屬性,例如 IOPS 和吞吐量,而無需刪除 PVC.
程式碼區塊_17
程式碼區塊_18
程式碼區塊_19
摘要
自 K8s 1.30-1.31 以來,隨著 CSI 成為強制平台,Kubernetes 中的儲存已顯著成熟。要記住的重點:
-
___HTMLTAG_240__HTMLTAG_241___emptyDir 用於 Pod 中的臨時共享存儲,PVC/PV 用於持久資料__HTMLTAG_245___
___HTMLTAG_246__HTMLTAG_247___需要 CSI:不再是 K8s 1.30+ 的樹內插件,必須遷移到 CSI 驅動程式
___HTMLTAG_250__HTMLTAG_251___StorageClass 動態設定是標準方式 — 管理員定義類,開發人員只需宣告
___HTMLTAG_254__HTMLTAG_255___Longhorn 對於具有分散式複製儲存的本地叢集來說是一個不錯的選擇
___HTMLTAG_258__HTMLTAG_259___磁碟區快照允許時間點備份/恢復,需要CSI驅動程式和快照控制器
___HTMLTAG_262__HTMLTAG_263___VolumeAttributesClass(K8s 1.29+ Beta)允許在不清除 PVC 的情況下更改 IOPS/吞吐量
- 總是使用
WaitForFirstConsumer與雲捲的綁定模式,以避免跨可用區附件問題