天天看點

幹貨解析 |為什麼要将快照引入Kubernetes?

Kubernetes v1.12引入了對volume snapshotting alpha的支援。此功能允許建立/删除卷快照,以及使用Kubernetes API本機建立新卷的功能。

1 什麼是快照?    

許多存儲系統(如Google Cloud Persistent Disks、Amazon Elastic Block Storage和許多内部部署存儲系統)都能夠建立持久卷的“快照”。快照表示卷的時間點副本。快照可用于配置新卷(預先填充快照資料)或将現有卷還原到先前狀态(由快照表示)。

2 為什麼要将快照引入到Kubernetes?

Kubernetes卷插件系統已經提供了一個強大的抽象功能,可以自動化塊和檔案存儲的配置、挂載和安裝。

支援所有這些功能的是Kubernetes工作負載可移植性的目标:Kubernetes旨在在分布式系統應用程式和底層叢集之間建立一個抽象層,以便應用程式可以與運作的叢集的細節無關,并且應用程式部署不需要“特定于叢集”的知識。

Kubernetes Storage SIG将快照操作定為許多有狀态工作負載的關鍵功能。例如,資料庫管理者可能希望在開始資料庫操作之前對資料庫卷進行快照。

通過提供在Kubernetes API中觸發快照操作的标準方法,Kubernetes使用者現在可以處理這樣的用例,而無需繞過Kubernetes API(并手動執行特定于存儲系統的操作)。

相反,Kubernetes使用者現在有權将叢集無關的快照操作合并到他們的工具和政策中,并且知道無論底層存儲如何,它都可以對任意Kubernetes叢集起作用。

此外,這些Kubernetes快照原語充當了基本建構塊,可以為Kubernetes開發進階企業級存儲管理功能:例如資料保護、資料複制和資料遷移。

3 哪個卷插件支援Kubernetes Snapshots?

Kubernetes支援三種類型的卷插件:in-tree、Flex和CSI。有關詳細資訊,請參閱Kubernetes Volume Plugin FAQ。

僅CSI驅動程式支援快照(不适用于in-tree或Flex)。要使用Kubernetes快照功能,請確定在叢集上部署實作快照的CSI驅動程式。

目前,以下CSI驅動程式支援快照:GCE Persistent Disk CSI Driver、OpenSDS CSI Driver、Ceph RBD CSI Driver、Portworx CSI Driver。

其他驅動程式的快照支援工作正在進行,應該很快就可以使用。閱讀“Kubernetes Goes Beta的容器存儲接口(CSI)”部落格文章,了解有關CSI以及如何部署CSI驅動程式的更多資訊。

4 Kubernetes Snapshots API

與管理Kubernetes Persistent Volumes的API類似,Kubernetes Volume Snapshots引入了三個用于管理快照的新API對象:

  • VolumeSnapshot——由Kubernetes使用者建立,以請求為指定卷建立快照。它包含有關快照操作的資訊,例如拍攝快照時的時間戳以及快照是否可以使用;與PersistentVolumeClaim對象類似,此對象的建立和删除表示使用者建立或删除叢集資源(快照)的願望。
  • VolumeSnapshotContent——成功建立快照後,由CSI卷驅動程式建立。它包含有關快照的資訊,包括快照ID;與PersistentVolume對象類似,此對象表示叢集上的已配置資源(快照);與PersistentVolumeClaim和PersistentVolume對象一樣,建立快照後,VolumeSnapshotContent對象将綁定到為其建立的VolumeSnapshot(使用一對一映射)。
  • VolumeSnapshotClass——由叢集管理者建立,以描述應如何建立快照。包括驅動程式資訊、通路快照的秘密等。

值得注意的是,與核心Kubernetes Persistent Volume對象不同,這些Snapshot對象被定義為CustomResourceDefinitions(CRD)。Kubernetes項目正逐漸遠離擁有API伺服器中預定義的資源類型,并且正朝着API伺服器獨立于API對象的模型發展。這允許API伺服器可以重用于Kubernetes以外的項目,而使用者(如Kubernetes)可以簡單地安裝它們作為CRD所需的資源類型。

支援快照的CSI驅動程式将自動安裝所需的CRD。Kubernetes最終使用者隻需要驗證支援快照的CSI驅動程式是否部署在其Kubernetes叢集上。

除了這些新對象之外,還在PersistentVolumeClaim對象中添加了一個新的DataSource字段:

type PersistentVolumeClaimSpec struct {

AccessModes []PersistentVolumeAccessMode

Selector *metav1.LabelSelector

Resources ResourceRequirements

VolumeName string

StorageClassName *string

VolumeMode *PersistentVolumeMode

DataSource *TypedLocalObjectReference

}

此新的alpha字段可以建立新卷,并使用現有快照中的資料自動預填充。

5 Kubernetes快照要求

在使用Kubernetes Volume Snapshotting之前,你必須:

  • 確定在Kubernetes叢集上部署并運作實施快照的CSI驅動程式。
  • 通過新的Kubernetes功能gate啟用Kubernetes Volume Snapshotting功能(預設情況下禁用alpha)
  • 在API伺服器二進制檔案上設定以下标志: – feature-gates = VolumeSnapshotDataSource = true

在建立快照之前,還需要通過建立VolumeSnapshotClass對象并将snapshotter字段設定為指向CSI驅動程式來為快照指定CSI驅動程式資訊。在下面的VolumeSnapshotClass示例中,CSI驅動程式是com.example.csi-driver。每個快照配置程式至少需要一個VolumeSnapshotClass對象。你還可以通過在類定義中放置注釋snapshot.storage.kubernetes.io/is-default-class:“true”來為每個單獨的CSI驅動程式設定預設的VolumeSnapshotClass。

apiVersion: snapshot.storage.k8s.io/v1alpha1

kind: VolumeSnapshotClass

metadata:

name: default-snapclass

annotations:

snapshot.storage.kubernetes.io/is-default-class: “true”

snapshotter: com.example.csi-driver

name: csi-snapclass

parameters:

fakeSnapshotOption: foo

csiSnapshotterSecretName: csi-secret

csiSnapshotterSecretNamespace: csi-namespace

你必須根據CSI驅動程式的文檔設定任何所需的不透明參數。如上面的示例所示,參數fakeSnapshotOption:foo和任何引用的秘密将在快照建立和删除期間傳遞給CSI驅動程式。預設CSI外部快照程式保留參數秘密csiSnapshotterSecretName和csiSnapshotterSecretNamespace。如果指定,它将擷取秘密并在建立和删除快照時将其傳遞給CSI驅動程式。

最後,在建立快照之前,你必須使用CSI驅動程式配置卷,并使用你想要快照的一些資料填充它(請參閱有關如何建立和使用CSI卷的CSI部落格文章)。

6 使用Kubernetes建立新快照

定義VolumeSnapshotClass對象并且你有要快照的卷後,可以通過建立VolumeSnapshot對象來建立新快照。

快照源指定要從中建立快照的卷。它有兩個參數:

  • kind ——必須是PersistentVolumeClaim
  • name —— PVC API對象名稱

假定卷的快照命名空間與VolumeSnapshot對象的命名空間相同。

kind: VolumeSnapshot

name: new-snapshot-demo

namespace: demo-namespace

spec:

snapshotClassName: csi-snapclass

source:

name: mypvc

kind: PersistentVolumeClaim

在VolumeSnapshot規範中,使用者可以指定VolumeSnapshotClass,其中包含有關應使用哪個CSI驅動程式建立快照的資訊。建立VolumeSnapshot對象時,VolumeSnapshotClass中的參數fakeSnapshotOption:foo和任何引用的秘密将通過CreateSnapshot調用傳遞給CSI插件com.example.csi-driver。

作為響應,CSI驅動程式觸發卷的快照,然後自動建立VolumeSnapshotContent對象以表示新快照,并将新的VolumeSnapshotContent對象綁定到VolumeSnapshot,使其可以使用。如果CSI驅動程式無法建立快照并傳回錯誤,則快照控制器将報告VolumeSnapshot對象狀态中的錯誤,并且不會重試(這與Kubernetes中的其他控制器不同,并且是為了防止意外在錯誤的時間拍攝快照)。

如果未指定快照類,外部快照程式将嘗試查找并為快照設定預設快照類。由預設快照類中的snapshotter指定的CSI驅動程式必須與PVC存儲類中的配置程式指定的CSI驅動程式比對。

請注意,Kubernetes Snapshot的alpha版本不提供任何一緻性保證。在拍攝快照以確定資料一緻性之前,你必須準備應用程式(暫停應用程式,當機檔案系統等)。

你可以通過運作kubectl describe volumesnapshot驗證是否已建立VolumeSnapshot對象并使用VolumeSnapshotContent綁定:

  • 應在Status下将Ready設定為true,以訓示此卷快照已準備就緒。
  • “Creation Time”字段訓示實際建立(剪切)快照的時間。
  • “Restore Size”字段表示從快照還原卷時的最小卷大小。
  • 規範中的“Snapshot Content Name”字段指向為此快照建立的VolumeSnapshotContent對象。

7 使用Kubernetes導入現有快照

你始終可以通過手動建立VolumeSnapshotContent對象來将現有快照導入Kubernetes,以表示現有快照。由于VolumeSnapshotContent是非命名空間API對象,是以隻有系統管理者才有權建立它。建立VolumeSnapshotContent對象後,使用者可以建立指向VolumeSnapshotContent對象的VolumeSnapshot對象。在驗證快照存在且VolumeSnapshot和VolumeSnapshotContent對象之間的綁定正确後,外部快照控制器會将快照标記為就緒。綁定後,快照就可以在Kubernetes中使用了。

應使用以下字段建立VolumeSnapshotContent對象,以表示預配置的快照:

  • csiVolumeSnapshotSource —— 快照辨別資訊。
  • snapshotHandle —— 快照的名稱/辨別符。這是必需字段。
  • 驅動程式 ——用于處理此卷的CSI驅動程式。這是必需字段。它必須與快照控制器中的快照程式名稱比對。
  • creationTime和restoreSize——預配置卷不需要這些字段。外部快照控制器将在建立後自動更新它們。
  • volumeSnapshotRef——指向此對象應綁定到的VolumeSnapshot對象的指針。name和namespace ——它指定内容綁定到的VolumeSnapshot對象的名稱和命名空間。
  • UID – 預配置卷不需要這些字段。外部快照控制器将在綁定後自動更新字段。如果使用者指定UID字段,則他/她必須確定它與綁定快照的UID比對。如果指定的UID與綁定快照的UID不比對,則該内容将被視為孤立對象,控制器将删除該對象及其關聯的快照。
  • snapshotClassName——此字段是可選的。外部快照控制器将在綁定後自動更新字段。

kind: VolumeSnapshotContent

name: static-snapshot-content

csiVolumeSnapshotSource:

driver: com.example.csi-driver

snapshotHandle: snapshotcontent-example-id

volumeSnapshotRef:

kind: VolumeSnapshot

name: static-snapshot-demo

namespace: demo-namespace

應建立VolumeSnapshot對象以允許使用者使用快照:

  • snapshotClassName——卷快照類的名稱。該字段是可選的。 如果設定,則快照類中的快照程式字段必須與快照控制器的快照程式名稱比對。如果未設定,快照控制器将嘗試查找預設快照類。
  • snapshotContentName——卷快照内容的名稱。預配置卷需要此字段。

name: static-snapshot-demo

snapshotContentName: static-snapshot-content

建立這些對象後,快照控制器将它們綁定在一起,并将字段Ready(在Status下)設定為True以訓示快照已準備就緒。

8 使用Kubernetes從快照配置新卷

要配置預先填充了來自快照對象的資料的新卷,請使用PersistentVolumeClaim中的新dataSource字段。 它有三個參數:

name——表示要用作源的快照的VolumeSnapshot對象的名稱

kind —— 必須是VolumeSnapshot

apiGroup —— 必須是snapshot.storage.k8s.io

假定源VolumeSnapshot對象的命名空間與PersistentVolumeClaim對象的命名空間相同。

apiVersion: v1

name: pvc-restore

Namespace: demo-namespace

storageClassName: csi-storageclass

dataSource:

name: new-snapshot-demo

apiGroup: snapshot.storage.k8s.io

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 1Gi

建立PersistentVolumeClaim對象時,它将觸發預先填充了來自指定快照的資料的新卷的配置。

9 作為存儲供應商,如何向CSI驅動程式添加對快照的支援?

要實作快照功能,CSI驅動程式必須添加對其他控制器功能CREATE_DELETE_SNAPSHOT和LIST_SNAPSHOTS的支援,并實作其他控制器RPC:CreateSnapshot、DeleteSnapshot和ListSnapshots。有關詳細資訊,請參閱CSI規範。

盡管Kubernetes盡可能在CSI卷驅動程式的打包和部署方面具有最低限度的規定,但它提供了在Kubernetes上部署任意容器化CSI驅動程式的建議機制,以簡化容器化CSI相容卷驅動程式的部署。

作為推薦部署過程的一部分,Kubernetes團隊提供了許多邊車(輔助)容器,包括一個新的外部快照邊車容器。

external-snapshotter監視Kubernetes API伺服器以查找VolumeSnapshot和VolumeSnapshotContent對象,并針對CSI端點觸發CreateSnapshot和DeleteSnapshot操作。 CSI外部供應商邊車容器也已更新,以支援使用新的dataSource PVC字段從快照恢複卷。

為了支援快照功能,建議存儲供應商除了外部配置器、外部挂載器以及它們的CSI驅動器之外,還要部署外部快照器邊車容器,如下圖所示。

在此示例中,部署yaml檔案、兩個邊車容器、外部配置器和外部快照器以及CSI驅動程式與statefulset pod中的hostpath CSI插件一起部署。 Hostpath CSI插件是一個示例插件,不适用于生産。

10 alpha有什麼限制?

Kubernetes快照的alpha實作具有以下限制:

  • 不支援将現有卷還原到快照表示的早期狀态(alpha僅支援從快照配置新卷)。
  • 不支援從快照中對現有PersistentVolumeClaim進行“就地恢複”:即從快照配置新卷,但更新現有PersistentVolumeClaim以指向新卷并有效地使PVC看起來恢複到早期狀态( alpha僅支援使用通過新PV / PVC從快照配置的新卷。
  • 沒有快照一緻性保證超出存儲系統提供的任何保證(例如崩潰一緻性)。

11 下一步是什麼?

根據回報和采用情況,Kubernetes團隊計劃将CSI Snapshot實施推向1.13或1.14中的beta。

12 怎樣才能了解更多?

請檢視有關快照功能的其他文檔:http://k8s.io/docs/concepts/storage/volume-snapshots和https://kubernetes-csi.github.io/docs/

13 如何參與?

像所有Kubernetes項目一樣,這個項目是許多來自不同背景的貢獻者共同努力的結果。

除了一直緻力于快照功能的貢獻者:Xing Yang(xing-yang)、Jing Xu(jingxu97)、Huamin Chen(rootfs)、Tomas Smetana(tsmetana)、Shiwei Xu(wackxu)之外,我們非常感謝Kubernetes Storage SIG和CSI社群的所有貢獻者,他們幫助稽核了項目的設計和實施,包括但不限于:Saad Ali (saadali)、Tim Hockin (thockin)、Jan Šafránek (jsafrane)、Luis Pabon (lpabon)、Jordan Liggitt (liggitt)、David Zhu (davidz627)、Garth Bushell (garthy)、Ardalan Kangarlou (kangarlou)、Seungcheol Ko (sngchlko)、Michelle Au (msau42)、Humble Devassy Chirammal (humblec)、Vladimir Vivien (vladimirvivien)、John Griffith (j-griffith)、Bradley Childs (childsb)、Ben Swartzlander (bswartz)、Michelle Au(msau42)、Humble Devassy Chirammal(humblec)、Vladimir Vivien(vladimirvivien)、John Griffith (j-griffith)、Bradley Childs (childsb)、Ben Swartzlander (bswartz)。

如果你有興趣參與CSI或Kubernetes存儲系統的任何部分的設計和開發,請加入Kubernetes存儲特别興趣小組(SIG)。

本文轉移K8S技術社群-幹貨解析 -

為什麼要将快照引入Kubernetes?