Kubernetes 1.32:卷組快照進入 Beta 階段
卷組快照在 Kubernetes 1.27 版本中作為 Alpha 特性被引入。最近釋出的 Kubernetes v1.32 將該支援提升到了 beta 階段。對卷組快照的支援依賴於一組用於組快照的擴充套件 API。這些 API 允許使用者為一組卷建立崩潰一致性快照。在後臺,Kubernetes 使用標籤選擇器將多個 PersistentVolumeClaim 分組以進行快照。一個關鍵目標是允許你將這組快照恢復到新的卷中,並基於一個崩潰一致的恢復點來恢復你的工作負載。
這項新功能僅支援 CSI 卷驅動。
卷組快照概述
一些儲存系統提供了建立多個卷的崩潰一致性快照的能力。組快照表示在同一時間點從多個卷建立的**副本**。組快照既可以用於重新生成新卷(預填充了快照資料),也可以用於將現有卷恢復到之前的狀態(由快照表示)。
為何向 Kubernetes 添加捲組快照?
Kubernetes 卷外掛系統已經提供了一個強大的抽象,可以自動執行塊儲存和檔案儲存的製備、掛接、掛載、調整大小和快照操作。
支撐所有這些特性的是 Kubernetes 的工作負載可移植性目標:Kubernetes 旨在在分散式應用程式和底層叢集之間建立一個抽象層,以便應用程式可以與它們執行的叢集的具體細節無關,並且應用程式部署不需要特定於叢集的知識。
已經有一個 VolumeSnapshot API,它提供了為持久卷建立快照以防止資料丟失或資料損壞的能力。然而,還有其他快照功能未被 VolumeSnapshot API 覆蓋。
一些儲存系統支援一致性組快照,允許在同一時間點從多個卷建立快照,以實現寫操作順序一致性。這對於包含多個卷的應用程式非常有用。例如,一個應用程式可能將資料儲存在一個卷中,將日誌儲存在另一個卷中。如果資料卷和日誌卷的快照在不同時間建立,當災難發生時,如果從這些快照恢復,應用程式將不一致,無法正常工作。
誠然,你可以先靜默應用程式,然後依次為作為應用程式一部分的每個卷建立單個快照,在所有單個快照都建立完畢後再取消靜默應用程式。這樣,你將獲得應用一致的快照。
然而,有時應用程式靜默可能非常耗時,以至於你希望減少靜默的頻率,或者可能根本無法靜默應用程式。例如,使用者可能希望每週執行一次帶有應用程式靜默的備份,而每晚執行一次不帶應用程式靜默但具有一致性組支援的備份,這種支援提供了組內所有卷的崩潰一致性。
用於卷組快照的 Kubernetes API
Kubernetes 對**卷組快照**的支援依賴於三種用於管理快照的 API Kind:
- VolumeGroupSnapshot
- 由 Kubernetes 使用者(或者可能由你自己的自動化)建立,用於請求為多個持久卷宣告建立一個卷組快照。它包含有關卷組快照操作的資訊,例如卷組快照的建立時間戳以及是否準備就緒。此物件的建立和刪除表示希望建立或刪除叢集資源(一個組快照)。
- VolumeGroupSnapshotContent
- 由快照控制器為動態建立的 VolumeGroupSnapshot 建立。它包含有關卷組快照的資訊,包括卷組快照 ID。此物件代表叢集上已製備的資源(一個組快照)。VolumeGroupSnapshotContent 物件與為其建立的 VolumeGroupSnapshot 存在一對一的繫結關係。
- VolumeGroupSnapshotClass
- 由叢集管理員建立,用於描述應如何建立卷組快照,包括驅動資訊、刪除策略等。
這三個 API Kind 被定義為CustomResourceDefinitions (CRD)。為了讓 CSI 驅動支援卷組快照,這些 CRD 必須安裝在 Kubernetes 叢集中。
支援卷組快照需要哪些元件
卷組快照在 external-snapshotter 倉庫中實現。實現卷組快照意味著新增或更改了幾個元件:
- 為 VolumeGroupSnapshot 和兩個支援性 API 添加了新的 CustomResourceDefinitions。
- 卷組快照控制器邏輯被新增到通用快照控制器中。
- 在 snapshotter sidecar 控制器中添加了呼叫 CSI 的邏輯。
卷快照控制器和 CRD 在每個叢集部署一次,而 sidecar 則與每個 CSI 驅動捆綁在一起。
因此,將卷快照控制器和 CRD 作為叢集外掛進行部署是合理的。
Kubernetes 專案建議 Kubernetes 發行版將卷快照控制器和 CRD 作為其 Kubernetes 叢集管理過程的一部分進行捆綁和部署(獨立於任何 CSI 驅動)。
Beta 版本有哪些新功能?
CSI 規範中的 VolumeGroupSnapshot 特性在 v1.11.0 版本中進入了 GA 階段。
快照驗證 webhook 在 external-snapshotter v8.0.0 中被棄用,現已被移除。大部分驗證 webhook 邏輯已作為驗證規則新增到 CRD 中。這些驗證規則要求的最低 Kubernetes 版本是 1.25。驗證 webhook 中有一項功能未移至 CRD,即防止為同一 CSI 驅動建立多個預設的卷快照類和多個預設的卷組快照類。隨著驗證 webhook 的移除,當為同一 CSI 驅動存在多個預設卷快照類或多個預設卷組快照類時,動態製備 VolumeSnapshot 或 VolumeGroupSnapshot 時仍會引發錯誤。
snapshot-controller 和 CSI snapshotter sidecar 中的
enable-volumegroup-snapshot
標誌已被特性門控取代。由於 VolumeGroupSnapshot 是一個新 API,該特性進入 Beta 階段,但特性門控預設是停用的。要使用此特性,請在啟動 snapshot-controller 和 CSI snapshotter sidecar 時新增標誌--feature-gates=CSIVolumeGroupSnapshot=true
來啟用該特性門控。動態建立 VolumeGroupSnapshot 及其對應的單個 VolumeSnapshot 和 VolumeSnapshotContent 物件的邏輯已從 CSI snapshotter 移至通用 snapshot-controller。新的 RBAC 規則已新增到通用 snapshot-controller 中,並且相應地從 CSI snapshotter sidecar 中刪除了一些 RBAC 規則。
我如何使用 Kubernetes 卷組快照
使用 Kubernetes 建立一個新的組快照
一旦定義了 VolumeGroupSnapshotClass 物件,並且你有一些想要一起快照的卷,你可以透過建立一個 VolumeGroupSnapshot 物件來請求一個新的組快照。
組快照的源(source)指定了底層的組快照是應該動態建立,還是應該使用一個預先存在的 VolumeGroupSnapshotContent。
預先存在的 VolumeGroupSnapshotContent 由叢集管理員建立。它包含了儲存系統上真實卷組快照的詳細資訊,可供叢集使用者使用。
必須設定組快照的源中的以下成員之一。
selector
- 一個針對要組合在一起進行快照的 PersistentVolumeClaim 的標籤查詢。此選擇器將用於匹配新增到 PVC 的標籤。volumeGroupSnapshotContentName
- 指定一個代表現有卷組快照的預先存在的 VolumeGroupSnapshotContent 物件的名稱。
動態製備組快照
在以下示例中,有兩個 PVC。
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-0 Bound pvc-6e1f7d34-a5c5-4548-b104-01e72c72b9f2 100Mi RWO csi-hostpath-sc <unset> 2m15s
pvc-1 Bound pvc-abc640b3-2cc1-4c56-ad0c-4f0f0e636efa 100Mi RWO csi-hostpath-sc <unset> 2m7s
為 PVC 新增標籤。
% kubectl label pvc pvc-0 group=myGroup
persistentvolumeclaim/pvc-0 labeled
% kubectl label pvc pvc-1 group=myGroup
persistentvolumeclaim/pvc-1 labeled
對於動態製備,必須設定一個選擇器,以便快照控制器可以找到帶有匹配標籤的 PVC,將它們一起進行快照。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshot
metadata:
name: snapshot-daily-20241217
namespace: demo-namespace
spec:
volumeGroupSnapshotClassName: csi-groupSnapclass
source:
selector:
matchLabels:
group: myGroup
在 VolumeGroupSnapshot 規約中,使用者可以指定 VolumeGroupSnapshotClass,其中包含有關應使用哪個 CSI 驅動來建立組快照的資訊。動態製備需要一個 VolumGroupSnapshotClass。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshotClass
metadata:
name: csi-groupSnapclass
annotations:
kubernetes.io/description: "Example group snapshot class"
driver: example.csi.k8s.io
deletionPolicy: Delete
卷組快照建立的結果是,將建立一個相應的 VolumeGroupSnapshotContent 物件,其 volumeGroupSnapshotHandle 指向儲存系統上的一個資源。
作為卷組快照建立的一部分,將建立兩個單獨的卷快照。
NAME READYTOUSE SOURCEPVC RESTORESIZE SNAPSHOTCONTENT AGE
snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0 true pvc-0 100Mi snapcontent-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0 16m
snapshot-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff true pvc-1 100Mi snapcontent-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff 16m
使用 Kubernetes 匯入現有組快照
要將一個預先存在的卷組快照匯入 Kubernetes,你還必須匯入相應的單個卷快照。
識別單個卷快照控制代碼,首先手動構造一個 VolumeSnapshotContent 物件,然後建立一個指向該 VolumeSnapshotContent 物件的 VolumeSnapshot 物件。對每個單個卷快照重複此操作。
然後手動建立一個 VolumeGroupSnapshotContent 物件,指定儲存系統上已存在的 volumeGroupSnapshotHandle 和單個 volumeSnapshotHandles。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshotContent
metadata:
name: static-group-content
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
groupSnapshotHandles:
volumeGroupSnapshotHandle: e8779136-a93e-11ef-9549-66940726f2fd
volumeSnapshotHandles:
- e8779147-a93e-11ef-9549-66940726f2fd
- e8783cd0-a93e-11ef-9549-66940726f2fd
volumeGroupSnapshotRef:
name: static-group-snapshot
namespace: demo-namespace
之後,建立一個指向該 VolumeGroupSnapshotContent 物件的 VolumeGroupSnapshot 物件。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshot
metadata:
name: static-group-snapshot
namespace: demo-namespace
spec:
source:
volumeGroupSnapshotContentName: static-group-content
如何在 Kubernetes 中使用組快照進行恢復
在恢復時,使用者可以請求從作為 VolumeGroupSnapshot 一部分的 VolumeSnapshot 物件建立一個新的 PersistentVolumeClaim。這將觸發製備一個新卷,該卷預先填充了來自指定快照的資料。使用者應重複此操作,直到從屬於組快照的所有快照中創建出所有卷。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: examplepvc-restored-2024-12-17
namespace: demo-namespace
spec:
storageClassName: example-foo-nearline
dataSource:
name: snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOncePod
resources:
requests:
storage: 100Mi # must be enough storage to fit the existing snapshot
作為儲存供應商,我如何為我的 CSI 驅動新增對組快照的支援?
要實現卷組快照功能,CSI 驅動**必須**:
- 實現一個新的組控制器服務。
- 實現組控制器 RPC:`CreateVolumeGroupSnapshot`、`DeleteVolumeGroupSnapshot` 和 `GetVolumeGroupSnapshot`。
- 新增組控制器能力 `CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT`。
更多詳細資訊,請參閱 CSI 規範和Kubernetes-CSI 驅動開發者指南。
如前所述,強烈建議 Kubernetes 發行版將卷快照控制器和 CRD 作為其 Kubernetes 叢集管理過程的一部分進行捆綁和部署(獨立於任何 CSI 驅動)。
作為此推薦部署過程的一部分,Kubernetes 團隊提供了許多 sidecar(輔助)容器,包括已更新以支援卷組快照的 external-snapshotter sidecar 容器。
external-snapshotter 監視 Kubernetes API 伺服器上的 VolumeGroupSnapshotContent 物件,並觸發針對 CSI 端點的 `CreateVolumeGroupSnapshot` 和 `DeleteVolumeGroupSnapshot` 操作。
有哪些限制?
Kubernetes 卷組快照的 Beta 實現有以下限制:
- 不支援將現有 PVC 恢復到由快照表示的早期狀態(僅支援從快照製備新卷)。
- 除了儲存系統提供的任何保證(例如崩潰一致性)之外,不提供應用程式一致性保證。有關應用程式一致性的更多討論,請參閱此文件。
下一步是什麼?
根據反饋和採用情況,Kubernetes 專案計劃在未來版本中將卷組快照實現推向正式釋出(GA)。
我如何瞭解更多資訊?
我如何參與?
這個專案,和所有 Kubernetes 專案一樣,是許多來自不同背景的貢獻者共同努力的成果。我謹代表 SIG Storage,向在過去幾個季度中挺身而出,幫助專案達到 Beta 階段的貢獻者們表示衷心的感謝:
- Ben Swartzlander (bswartz)
- Cici Huang (cici37)
- Hemant Kumar (gnufied)
- James Defelice (jdef)
- Jan Šafránek (jsafrane)
- Madhu Rajanna (Madhu-1)
- Manish M Yathnalli (manishym)
- Michelle Au (msau42)
- Niels de Vos (nixpanic)
- Leonardo Cecchi (leonardoce)
- Rakshith R (Rakshith-R)
- Raunak Shah (RaunakShah)
- Saad Ali (saad-ali)
- Xing Yang (xing-yang)
- Yati Padia (yati1998)
對於有興趣參與 CSI 或 Kubernetes 儲存系統任何部分的設計和開發的人,歡迎加入 Kubernetes 儲存特別興趣小組 (SIG)。我們隨時歡迎新的貢獻者。
我們還定期舉行資料保護工作組會議。歡迎新成員加入我們的討論。