前言
CSI snapshot 是由華為在 Kubernetes 社群主導開發的儲存特性,在 K8S 1.12進入Alpha階段。接下來,我們將分為上下兩篇,分別介紹snapshot的建立刪除等API以及從snapshot還原資料卷,同時,我們將使用CSI hostpath 外掛來演示,如何使用這兩種特性。
Kubernetes CSI Snapshot(上篇)
背景
許多儲存系統提供了建立儲存卷“快照”(snapshot)的能力,以防止資料丟失。快照可以替代傳統的備份系統來備份和還原主要資料和關鍵資料。快照能夠快速備份資料(例如,建立GCE PD快照僅需要幾分之一秒), 並提供快速恢復時間目標(RTO)和恢復點目標(RPO)。快照還可用於資料複製、分發和遷移。 早在kubernetes 1.8版本中,卷快照系統原型已經發布,其實現位於 external-storage(github.com/kubernetes-…)庫中。該原型基於 CRD 實現,提供了外部 controller 和 provisioner 兩個二進位制,支援 GCE PD,AWS EBS,OpenStack Cinder,GlusterFS 和 Kubernetes hostPath 等儲存卷。
Kubernetes 的社群儲存趨勢是採用 CSI 實現儲存外掛,本文新增對 CSI 儲存外掛的快照支援。Kubernetes 的趨勢是保持核心 API 儘可能小,因此我們採用 CRD 實現,並新增一個外部快照控制器來處理卷快照,external provisioner 也會升級以支援從快照建立 volume,CSI snapshot規範詳情可以在https://github.com/container-storage-interface/spec/pull/224 檢視。
目標
對於 Kubernetes 中的第一個快照支援版本,我們僅支援 CSI 卷外掛按需建立快照。
- 目標1:實現標準化的快照操作,支援建立,列出和刪除快照等 REST API。目前,API 將使用 CRD(CustomResourceDefinitions)實現。
- 目標2:實現CSI卷快照支援。
external-snapshotter
將與 CSI 卷外掛的其他外部元件(例如,external-attacher, external-provisioner
)一起部署。 - 目標3:提供一種從快照建立新儲存卷和還原現有卷的便捷方法。 以下目標本階段將不會實現,但將在稍後階段考慮。
- 目標4:通過提供
pre/post
快照鉤子來凍結/解凍應用程式和/或解除安裝/掛載檔案系統,從而提供應用程式一致性快照。 - 目標5:提供更高階別的管理,例如備份和還原 pod 和 statefulSet,以及建立一致性的快照組。
詳細設計
在此提案中,卷快照被視為 Kubernetes 管理的另一種儲存資源。 因此,快照 API 和控制器遵循現有卷管理的設計模式。
- VolumeSnapshot
- VolumeSnapshotContent
- VolumeSnapshotClass
三個 API,它們與 PersistentVolumeClaim 和 PersistentVolume 以及 storageClass 的結構類似。外部快照控制器的功能類似於 in-tree
的 PV 控制器。同時建議在 PersistentVolumeClaim(PVC)API 中新增新的資料來源結構,以支援從快照還原資料卷。 以下部分將詳細介紹 API 和控制器設計。
Snapshot API設計
VolumeSnapshot 和 VolumeSnapshotContent API 是在 PersistentVolumeClaim 和 PersistentVolume 之後建模設計的。 在第一個版本中,VolumeSnapshot 生命週期完全獨立於其來源(PVC)。 刪除 PVC / PV
時,相應的 VolumeSnapshot 和 VolumeSnapshotContent 物件將繼續存在。 但是,對於某些卷外掛,快照依賴於其儲存卷。 在未來的版本中,我們計劃進行完整的生命週期管理,以便更好地處理快照與其卷之間的關係。(例如,新增finalizer,當有快照依賴於儲存卷時,可防止儲存卷被刪除)。
VolumeSnapshot物件
VolumeSnapshotContent物件
VolumeSnapshotClass物件
我們將新增新的 API 物件 VolumeSnapshotClass,而不是複用現有的 StorageClass,以避免在 snapshot 和 volume 之間混合引數。每個 CSI 卷外掛都可以擁有自己的預設 VolumeSnapshotClass。如果未提供 VolumeSnapshotClass,則將使用預設值。VolumeSnapshotClass 將為快照新增新的引數。
Snapshot Controller 設計要點
如下圖所示,CSI 快照控制器體系結構由 external-snapshotter
(外部快照器)組成,external-snapshotter
通過套接字與 out-of-tree
CSI 卷外掛進行通訊(預設情況下為/ run / csi / socket
,可由 -csi-address
配置)。external-snapshotter 是 Kubernetes 實現容器儲存介面(CSI)的一部分。 它是一個外部控制器,用於監視 VolumeSnapshot 和 VolumeSnapshotContent 物件並建立/刪除快照。
- 通常
external-snapshotter
使用ControllerGetCapabilities
來驗證 CSI 驅動程式是否支援CREATE_DELETE_SNAPSHOT
呼叫。 external-snapshotter
負責建立/刪除快照及繫結 VolumeSnapshot 和 VolumeSnapshotContent 物件。它遵循 kubernetes 控制器模式並使用 informer 來監視 VolumeSnapshot 和 VolumeSnapshotContent 建立/更新/刪除事件。通過 Snapshotter == <CSI 卷外掛名字>過濾掉不符合的 VolumeSnapshot 例項,並使用具有指數退避的工作佇列處理這些事件。- 對於動態建立的快照,它應該關聯某個 VolumeSnapshotClass。使用者可以在 VolumeSnapshot API 物件中顯式指定 VolumeSnapshotClass。如果使用者未指定 VolumeSnapshotClass,則將使用 admin 建立的預設 VolumeSnapshotClass。這和使用預設的 StorageClass 來配置 PersistentVolumeClaim 相似。
- 對於靜態繫結快照,
user/admin
必須為 VolumeSnapshot 和 VolumeSnapshotContent 正確指定雙向指標,以便控制器知道如何繫結它們。否則,如果 VolumeSnapshot 指向不存在的 VolumeSnapshotContent,或者是 VolumeSnapshotContent 並未指向 VolumeSnapshot,則將 VolumeSnapshot 設定為錯誤狀態。 - 針對每一個 CSI 卷外掛,external-snapshotter、external-attacher和external-provisioner 執行在同一個 sidecar 中。
- 在當前設計中,當儲存系統無法建立快照時,將不會在控制器中執行重試。這是因為當快照建立的時間很重要時,使用者可能不想在獲取一致性快照或計劃快照時重試。在將來的版本中,將新增 maxRetries 標誌或重試終止時間戳,以允許使用者控制是否需要重試。
本篇文章主要介紹了 snapshot 的 API 物件,以及 external-snapshotter
的架構設計和實現原理,下篇文章,我們將會介紹從snapshot 還原資料卷,以及演示如何使用這兩種特性,敬請期待。