1. 程式人生 > >容器服務 TKE 儲存外掛與雲硬碟 CBS 最佳實踐應用

容器服務 TKE 儲存外掛與雲硬碟 CBS 最佳實踐應用

## 引言 隨著自研上雲的深入,越來越多的有狀態服務對於在 TKE 叢集中使用雲上儲存能力的需求也越來越強烈。 目前 [騰訊雲容器服務 TKE(Tencent Kubernetes Engine)](https://cloud.tencent.com/product/tke)已支援在 TKE 叢集中的應用使用多種儲存服務,包括 [雲硬碟 CBS](https://cloud.tencent.com/product/cbs)、[檔案儲存 CFS](https://cloud.tencent.com/product/cfs) 以及 [物件儲存 COS](https://cloud.tencent.com/product/cos)。TKE 通過兩種儲存外掛(In-Tree 和 CSI)來支援上述能力,使用者可以通過雲控制檯很方便地選擇儲存型別並建立對應的 PV/PVC。但仍然會有一些問題困擾著大家,比如:TKE 叢集中是否支援擴容 CBS 雲盤;如果叢集跨可用區,如何避免叢集中頻繁出現掛載(attach)失敗;TKE 中是否支援快照功能;我的應用應該選擇哪種型別儲存;In-Tree 和 CSI 都支援 CBS,二者有和區別,是否能把之前使用 In-Tree 外掛建立的雲盤轉變為 CSI 外掛管理等。 對於 TKE 儲存的相關問題,這裡會詳細介紹。接下來,我們先概覽下 Kubernetes 持久化儲存的流程 ## Kubernetes 持久化儲存流程 這裡對 Kubernetes 持久化儲存的流程做個概覽,不深入各個元件。 ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104538693-1022645811.png) 建立一個使用了持久化儲存的 pod 的流程包含以下步驟: 1. 使用者建立一個引用PVC的 pod(動態建立PV); 2. **Scheduler**根據 pod 的配置、節點狀態、PV 配置等其他因素把 pod 排程到一個合適的 node 上; 3. **PV Controller** watch 到 PVC,呼叫 Volume Plugin 去建立 PV,並繫結 PV 和 PVC。如果是 out-of-tree 儲存外掛(如 CSI),則建立 PV 實際是由 external provisioner 完成,之後 PV Controller 完成 PV 和 PVC 的bound;如果是 in-tree 外掛,但是通過`kubernetes-sigs/sig-storage-lib-external-provisioner`實現了一個 external provisioner,則與 out-of-tree 外掛相同;如果是 in-tree 外掛,且外掛直接實現了相應的創刪介面,則 PV Controller 直接呼叫 in-tree 外掛的實現完成建立 PV。 4. **AD Controller** 對比 asw 和 dsw 狀態,發現 Volume 需要被 attach,則呼叫 Volume Plugin 的實現去 attach。in-tree 外掛不需多說,如果是 CSI 外掛,則 AD Controller 會先呼叫 CSI in-tree 程式碼建立 VolumeAttachment 物件,CSI 外掛的一個名為 external-attacher 的 sidecar 會 watch 該物件,watch 到建立則呼叫 CSI driver 的相應方法(`ControllerPublishVolume`)來 attach。 5. **VolumeManager** 等到 volume 成功 attach 到節點後,開始呼叫 Volume Plugin 去進行 mount 操作。這個mount 操作分為兩步:第一步是格式化裝置並把 volume mount 到一個 global mount path(`/var/lib/kubelet/plugins`下),第二步是將 bind mount 剛才的 global mount path到`/var/lib/kubelet/pods/${pod_UUID}/volumes`下。 6. **Kubelet** 呼叫容器執行時啟動容器,並且 bind mount 第5步中的 mount path 到容器中。 **(Provision -> Attach -> Mount; Unmount -> Detach -> Delete)** ## TKE 儲存外掛及原理介紹 隨著 Kubernetes 社群發展,TKE 先後支援了 In-Tree 和 CSI 兩種儲存外掛。二者在功能上的主要區別在於 In-Tree 儲存外掛僅支援在 TKE 叢集使用 CBS,而 CSI 支援使用 CBS、CFS、COS。 | 型別 | 支援CBS | 支援CFS | 支援COS | 參考 | | ------- | ------- | ------- | ------- | ----------------------------------------------------------- | | In-Tree | √ | × | × | | | CSI | √ | √ | √ | https://github.com/TencentCloud/kubernetes-csi-tencentcloud | ### In-Tree 外掛(QcloudCbs) - kubernetes 早期只支援以 In-Tree 的方式擴充套件儲存外掛,也就是外掛在 Kubernetes 程式碼中實現。 - In-Tree 外掛名為`cloud.tencent.com/qcloud-cbs`,所以也可稱為 QcloudCbs,在 TKE 叢集中有個預設的名為`cbs`的 StorageClass。 ``` NAME PROVISIONER AGE cbs (default) cloud.tencent.com/qcloud-cbs 48m ``` #### 特性 In-Tree 外掛只實現了使用 CBS 的能力,其主要特性有: - **靜態資料卷**:即使用者手動建立 volme、PV 物件、PVC 物件 - **動態資料卷**:根據 StorageClass 配置來由外掛控制建立和刪除 volume 和 PV - **拓撲感知**:CBS 不支援跨可用區掛載,在多可用區叢集中,會先排程 pod,然後去排程後的 node 的 zone 建立 volume。 - **排程器感知節點 maxAttachLimit**:騰訊雲單個 CVM 上預設最多掛載 20塊 CBS 盤,排程器感知該限制,排程時過濾到要超過 maxAttachLimit 的節點。可以全域性修改 maxAttachLimit,但需要 IaaS 層先支援。
騰訊雲端儲存靜態資料卷動態資料卷拓撲感知排程器感知節點 maxAttachLimit
騰訊雲硬碟(CBS)支援兩種使用方式:
  • 直接通過 volume 使用
  • 通過PV/PVC使用(推薦)
  • 支援支援。pod 排程後,在同一個可用區建立 volume。避免 CBS 跨可用區無法使用。支援。雲伺服器(cvm)可以掛載的雲硬碟(cbs)是有上限的。排程器排程 pod 時過濾掉超過最大可掛載 CBS 數量的節點。
    #### 原理簡介 下面簡單瞭解下 In-Tree 外掛 QcloudCbs 的架構圖,瞭解各相關元件分別完成何種工作。 ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104538860-2010166863.png) 上圖是包含 TKE In-Tree 儲存外掛的 Kubernetes 儲存架構圖。圖中綠色部分,皆屬於 In-Tree 外掛 QcloudCbs 的實現範疇。 由上述的 **Kubernetes持久化儲存流程** 可知要動態使用一個 cbs pv,主要有三個過程:provision、attach、mount,而這三個過程是由不同元件負責的: - **cbs-provisioner** 負責 volume 的 provision/delete。為了與 Kubernetes 程式碼解耦,cbs-provisioner 是基於`kubernetes-sigs/sig-storage-lib-external-provisioner`實現的一個 **external provisioner**,來 provision 和 delete volume。PV Controller 在這種模式下雖然不去 provision/delete volume,但是還是會參與處理(比如 PV 和 PVC 的繫結)。 - **AD Controller** 負責 volume 的 attach/detach。Tencent Cloud Provider 中封裝雲 API,In-Tree 外掛呼叫 Cloud Provider 實現了 attach/detach 的具體邏輯,並提供給 AD Controller 呼叫。 - kubelet 的 **Volume Manager** 負責 volume 的 mount/unmount。In-Tree 外掛中實現 MountDevice、SetUp 等介面,Volume Manager 呼叫其完成準備 volume 的最後一步。 - 另外,**Scheduler** 中也有 volume 相關的邏輯,我們添加了一個 predicate 策略:**`MaxQcloudCbsVolumeCount`**,該策略主要實現**排程器感知節點 maxAttachLimit**特性。而 Scheduler 原生的一個 predicate 策略:**`NoVolumeZoneConflictPred`**,是用來把 pod 排程到已有 PV 所在 zone 的節點,這可以避免雲盤跨可用區掛載的問題;對於新建 PV 的話,避免雲盤跨可用區掛載問題則由**拓撲感知**特性完成。 ### CSI 外掛 CSI 是 Kubernetes 社群擴展卷的標準和推薦方式。TKE 的 CSI 外掛包含 CBS、CFS、COS 三個 driver,本節重點介紹 CBS CSI driver,並與 QcloudCbs 進行對比。3個 driver 的靜態 pv 和動態 pv 的支援情況如下表所示: | 騰訊雲端儲存 | 靜態資料卷 | 動態資料卷 | | --------------- | ---------- | ---------- | | 雲硬碟(CBS) | 支援 | 支援 | | 檔案儲存(CFS) | 支援 | 支援 | | 物件儲存(COS) | 支援 | 不支援 | #### CBS CSI 特性及與 QcloudCbs 對比 - CBS CSI 比 QcloudCbs 多幾個特性:volume 線上擴容,volume 快照和恢復。 | 儲存外掛 | 靜態資料卷 | 動態資料卷 | 拓撲感知 | 排程器感知節點maxAttachLimit | 卷線上擴容 | 卷快照&恢復 | | -------------------- | ---------- | ---------- | -------- | ---------------------------- | ---------- | ----------- | | CBS CSI | √ | √ | √ | √ | √ | √ | | QcloudCbs(In-Tree) | √ | √ | √ | √ | × | × | #### 原理簡介 ##### CSI 原理簡介 ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104539368-97257227.png) CSI 原理參考上圖。要實現一個 CSI driver,一般需要實現以下 3 個 gRPC services(CSI Controller Service 可選): - **CSI Identity Services**:提供 driver 資訊(drivername,版本等) - ***CSI Controller Services*** (可選):controller 負責創刪卷、attach/detach、擴容、快照等。涉及的方法如下: - CreateVolume/DeleteVolume - Controller[Publish|Unpublish]Volume (對應attach/detach) - CreateSnapshot/DeleteSnapshot/ListSnapshots - ControllerExpandVolume - ***CSI Node Services*** :負責向節點註冊 driver,mount/unmount。涉及的方法如下: - NodeStageVolume/NodeUnstageVolume((un)mount device) - NodePublishVolume/NodeUpPublishVolume((un)mount volume) 在我們實現之外,kuberntes Team 還提供了多個外部元件,用於溝通 k8s 原生元件(apiserver、controller manager、kubelet)與自己實現的 CSI driver。 - **external-provisioner**:watch `PersistentVolumeClaim`(PVC)物件,呼叫 driver 的`CreateVolume/DeleteVolume` - **external-attacher**:watch `VolumeAttachment`物件,呼叫 driver 的`Controller[Publish|Unpublish]Volume` - **external-resizer**: watch `PersistentVolumeClaim`物件,呼叫 driver 的`ControllerExpandVolume` - **external-snapshotter**和**snapshot-controller**:snapshot-controller watch `VolumeSnapshot`和`VolumeSnapshotContent` CRD 物件,external-snapshotter watch `VolumeSnapshotContent`物件。呼叫 driver 的`CreateSnapshot/DeleteSnapshot/ListSnapshots` - ***node-driver-registrar\***:使用`NodeGetInfo`獲取 driver 資訊,然後使用 kubelet 外掛註冊機制註冊 driver。 ##### CBS CSI 部署圖 CBS CSI 使用社群推薦部署方式,包含兩個 workload: - 一個 DaemonSet,也就是每個 Node 會有一個,我們可以簡單稱為`NodePlugin`,由 CBS CSI Driver 和 node-driver-registrar 兩個容器組成。負責向節點註冊 driver,並提供 mount 的能力。 - 一個 StatefulSet/Deployment,我們可以簡稱為`Controller`。由 driver 和多個 sidecar(external-provisioner、external-attacher、external-resizer、external-snapshotter、snapshot-controller)一起構成,提供創刪卷、attach/detach、擴容、快照等能力 ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104540059-620719057.png) ##### CBS CSI 外掛的 mount 是 driver 容器執行的,它是如何 mount 到 Node 上的? - 答案是:掛載傳播(Mount propagation)。掛載傳播允許容器內的 mount 在容器外可見。參見https://stupefied-goodall-e282f7.netlify.app/contributors/design-proposals/node/propagation/ - CBS CSI 的 global mount 階段(NodeStageVolume)要把裝置 mount 到`/var/lib/kubelet/plugins`的子目錄下;之後 bind mount 階段(NodePublishVolume)的 target path 是`/var/lib/kubelet/pods`。所以我們為這兩個目錄都設定了掛載傳播(模式為`Bidirectional`) ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104540559-55581440.png) ## 使用推薦 - TKE 叢集版本為 1.14+(包含 1.14),推薦使用 CSI 外掛 - 需要在TKE叢集中使用 CFS 和 COS 能力,使用 CSI 外掛 - 需要在TKE叢集中對 CBS 盤線上擴容和使用快照功能,使用 CSI 外掛 - 已經使用了 QcloudCbs(In-Tree 外掛)的,可以繼續使用。(後續會通過 Volume Migration 統一到 CBS CSI) ## 最佳實踐 provisioner: - cbs csi —— "com.tencent.cloud.csi.cbs" - cbs intree —— "cloud.tencent.com/qcloud-cbs" cbs csi 的安裝請參見 [cbs csi 文件](https://github.com/TencentCloud/kubernetes-csi-tencentcloud/blob/master/docs/README_CBS.md),我們也已經在騰訊雲控制檯支援擴充套件元件安裝。 > 本節最佳實踐均以 cbs csi 外掛為例,相應版本要求也是針對 cbs csi 外掛。 ### 1、如果叢集節點跨 zone,如何避免 cbs 雲盤跨可用區掛載? cbs 雲盤不支援跨可用區掛載到節點,所以在跨可用區的叢集中推薦通過**拓撲感知**特性來避免跨可用區掛載的問題。 #### 1.1 使用前注意 - TKE叢集版本 >= 1.14 - 確保 csi 外掛為最新版本 #### 1.2 如何使用 使用方式很簡單,在 storageclass 中設定 `volumeBindingMode`為**`WaitForFirstConsumer`**,然後使用該 storageClass 即可。intree 和 csi 外掛均支援。 ``` kind: StorageClass metadata: name: cbs-topo parameters: type: cbs provisioner: com.tencent.cloud.csi.cbs reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer ``` #### 1.3 原理 拓撲感知排程需要多個 k8s 元件配合完成,包括 scheduler、pv controller、external-provisioner。流程為: 1. pv controller watch 到 PVC 物件,發現 storageclass 的 volumeBindingMode 為`WaitForFirstConsumer`,即不會馬上處理該pvc的建立事件,等待 scheduler 處理; 2. scheduler 排程完 pod 後,會將 nodeName 以 annotation 的方式打到 PVC 物件上: `volume.kubernetes.io/selected-node: 10.0.0.72` 3. pv controller 獲取到 PVC 物件的更新事件後,處理這個 annotation(`volume.kubernetes.io/selected-node`),根據 nodeName 獲取 Node 物件,傳入到 provisioner 中。 4. provisioner 根據傳過來的 Node 物件的 label 獲取可用區(`failure-domain.beta.kubernetes.io/zone`),之後在對應 zone 建立 pv,從而達到和 pod 相同可用區的效果,避免雲盤和 node 在不同可用區而無法掛載。 ### 2、如何線上擴容雲盤? TKE 支援線上擴容 PV,對應的雲盤及檔案系統,即不需要重啟 pod 即可完成擴容。但,為了確保檔案系統的穩定性,還是推薦先讓雲盤檔案系統處於未 mount 情況下。為此,我們將提供兩種擴容方式: 1. 不重啟 pod 的情況下線上擴容 - 這種情況下被擴容的雲盤的檔案系統被 mount 在節點上,如果 I/O 的話,有可能會出現檔案系統擴容錯誤 2. 重啟 pod 的情況下線上擴容 - 這種情況下被擴容的雲盤的檔案系統被 unmount了。可以避免上面的問題,**推薦這種方式**。 #### 2.1 使用前注意 - TKE叢集版本 >= 1.16,詳見 [cbs csi 文件](https://github.com/TencentCloud/kubernetes-csi-tencentcloud/blob/master/docs/README_CBS.md) - 僅 cbs csi 外掛支援擴容,確保 csi 外掛為最新版本 - 可以在擴容前使用快照來備份資料,避免擴容失敗導致資料丟失。參見下方 3.2.1 使用快照備份雲硬碟 #### 2.2 如何使用 ##### 2.2.1 建立允許擴容的 StorageClass 在 storageclass 中設定`allowVolumeExpansion`為`true`: ``` allowVolumeExpansion: true apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cbs-csi-expand parameters: diskType: CLOUD_PREMIUM provisioner: com.tencent.cloud.csi.cbs reclaimPolicy: Delete volumeBindingMode: Immediate ``` ##### 2.2.2 不重啟 pod 的情況下線上擴容 1、確認擴容前 pv 和檔案系統狀態,大小均為 20G ``` $ kubectl exec ivantestweb-0 df /usr/share/nginx/html Filesystem 1K-blocks Used Available Use% Mounted on /dev/vdd 20511312 45036 20449892 1% /usr/share/nginx/html $ kubectl get pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c 20Gi RWO Delete Bound default/www1-ivantestweb-0 cbs-csi 20h ``` 2、執行以下命令修改 PVC 物件中的容量,擴容至 30G ``` $ kubectl patch pvc www1-ivantestweb-0 -p '{"spec":{"resources":{"requests":{"storage":"30Gi"}}}}' ``` 執行後稍等片刻,可以發現 pv 和檔案系統已經擴容至 30G: ``` $ kubectl exec ivantestweb-0 df /usr/share/nginx/html Filesystem 1K-blocks Used Available Use% Mounted on /dev/vdd 30832548 44992 30771172 1% /usr/share/nginx/html $ kubectl get pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c 30Gi RWO Delete Bound default/www1-ivantestweb-0 cbs-csi 20h ``` ##### 2.2.3 重啟 pod 的情況下線上擴容 1、確認擴容前 pv 和檔案系統狀態,大小均為 30G ``` $ kubectl exec ivantestweb-0 df /usr/share/nginx/html Filesystem 1K-blocks Used Available Use% Mounted on /dev/vdd 30832548 44992 30771172 1% /usr/share/nginx/html $ kubectl get pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c 30Gi RWO Delete Bound default/www1-ivantestweb-0 cbs-csi 20h ``` 2、使用下面命令給 PV 物件打標籤,打一個非法 zone,旨在下一步重啟 pod 後 pod 無法排程到某個節點上 ``` $ kubectl label pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c failure-domain.beta.kubernetes.io/zone=nozone ``` 3、重啟 pod。重啟後由於 pod 對應的 pv 的標籤表明的是非法 zone,pod 會處於 Pending 狀態 ``` $ kubectl delete pod ivantestweb-0 $ kubectl get pod ivantestweb-0 NAME READY STATUS RESTARTS AGE ivantestweb-0 0/1 Pending 0 25s $ kubectl describe pod ivantestweb-0 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 40s (x3 over 2m3s) default-scheduler 0/1 nodes are available: 1 node(s) had no available volume zone. ``` 4、修改 PVC 物件中的容量,擴容至 40G ``` kubectl patch pvc www1-ivantestweb-0 -p '{"spec":{"resources":{"requests":{"storage":"40Gi"}}}}' ``` 5、去掉 PV 物件之前打的標籤,這樣 pod 就能排程成功了。 ``` $ kubectl label pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c failure-domain.beta.kubernetes.io/zone-persistentvolume/pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c labeled ``` 稍等片刻,pod running,對應的 pv 和檔案系統也擴容成功,從 30G 擴容到 40G 了 ``` $ kubectl get pod ivantestweb-0 NAME READY STATUS RESTARTS AGE ivantestweb-0 1/1 Running 0 17m $ kubectl get pv pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c 40Gi RWO Delete Bound default/www1-ivantestweb-0 cbs-csi 20h $ kubectl get pvc www1-ivantestweb-0 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www1-ivantestweb-0 Bound pvc-e193201e-6f6d-48cf-b96d-ccc09225cf9c 40Gi RWO cbs-csi 20h $ kubectl exec ivantestweb-0 df /usr/share/nginx/html Filesystem 1K-blocks Used Available Use% Mounted on /dev/vdd 41153760 49032 41088344 1% /usr/share/nginx/html ``` ### 3、如何建立快照和使用快照來恢復卷? #### 3.1 使用前注意 - TKE叢集版本 >= 1.18,詳見 [cbs csi 文件](https://github.com/TencentCloud/kubernetes-csi-tencentcloud/blob/master/docs/README_CBS.md) - 僅 cbs csi 外掛支援快照,確保 csi 外掛映象為最新版本 #### 3.2 如何使用 ##### 3.2.1 使用快照備份雲硬碟 1、使用下面 yaml,建立`VolumeSnapshotClass`物件 ``` apiVersion: snapshot.storage.k8s.io/v1beta1 kind: VolumeSnapshotClass metadata: name: cbs-snapclass driver: com.tencent.cloud.csi.cbs deletionPolicy: Delete ``` 建立後顯示: ``` $ kubectl get volumesnapshotclass NAME DRIVER DELETIONPOLICY AGE cbs-snapclass com.tencent.cloud.csi.cbs Delete 17m ``` 2、使用下面 yaml,建立 ``` apiVersion: snapshot.storage.k8s.io/v1beta1 kind: VolumeSnapshot metadata: name: new-snapshot-demo spec: volumeSnapshotClassName: cbs-snapclass source: persistentVolumeClaimName: csi-pvc ``` 建立後稍等片刻,volumesnapshot 和 volumesnapshotcontent 物件都建立成功,`READYTOUSE`為 true: ``` $ kubectl get volumesnapshot NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE new-snapshot-demo true www1-ivantestweb-0 10Gi cbs-snapclass snapcontent-ea11a797-d438-4410-ae21-41d9147fe610 22m 22m $ kubectl get volumesnapshotcontent NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT AGE snapcontent-ea11a797-d438-4410-ae21-41d9147fe610 true 10737418240 Delete com.tencent.cloud.csi.cbs cbs-snapclass new-snapshot-demo 22m ``` 具體快照 id 在 volumesnapshotcontent 物件中,`status.snapshotHandle`(snap-e406fc9m),可以根據這個快照 id 在騰訊雲控制檯確認快照是否存在 ``` $ kubectl get volumesnapshotcontent snapcontent-ea11a797-d438-4410-ae21-41d9147fe610 -oyaml apiVersion: snapshot.storage.k8s.io/v1beta1 kind: VolumeSnapshotContent metadata: creationTimestamp: "2020-11-04T08:58:39Z" finalizers: - snapshot.storage.kubernetes.io/volumesnapshotcontent-bound-protection name: snapcontent-ea11a797-d438-4410-ae21-41d9147fe610 resourceVersion: "471437790" selfLink: /apis/snapshot.storage.k8s.io/v1beta1/volumesnapshotcontents/snapcontent-ea11a797-d438-4410-ae21-41d9147fe610 uid: 70d0390b-79b8-4276-aa79-a32e3bdef3d6 spec: deletionPolicy: Delete driver: com.tencent.cloud.csi.cbs source: volumeHandle: disk-7z32tin5 volumeSnapshotClassName: cbs-snapclass volumeSnapshotRef: apiVersion: snapshot.storage.k8s.io/v1beta1 kind: VolumeSnapshot name: new-snapshot-demo namespace: default resourceVersion: "471418661" uid: ea11a797-d438-4410-ae21-41d9147fe610 status: creationTime: 1604480319000000000 readyToUse: true restoreSize: 10737418240 snapshotHandle: snap-e406fc9m ``` ##### 3.2.2 從快照恢復卷(雲硬碟) 1、我們在 3.2.1 中建立的`VolumeSnapshot`的物件名為`new-snapshot-demo`,使用下面 yaml 來從快照恢復一個卷 ``` apiVersion: v1 kind: PersistentVolumeClaim metadata: name: restore-test spec: storageClassName: cbs-csi dataSource: name: new-snapshot-demo kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io accessModes: - ReadWriteOnce resources: requests: storage: 10Gi ``` 發現 restore 的 pvc 已經創建出來,diskid 也在 pv 中(disk-gahz1kw1) ``` $ kubectl get pvc restore-test NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE restore-test Bound pvc-80b98084-29a3-4a38-a96c-2f284042cf4f 10Gi RWO cbs-csi 97s $ kubectl get pv pvc-80b98084-29a3-4a38-a96c-2f284042cf4f -oyaml apiVersion: v1 kind: PersistentVolume metadata: annotations: pv.kubernetes.io/provisioned-by: com.tencent.cloud.csi.cbs creationTimestamp: "2020-11-04T12:08:25Z" finalizers: - kubernetes.io/pv-protection name: pvc-80b98084-29a3-4a38-a96c-2f284042cf4f resourceVersion: "474676883" selfLink: /api/v1/persistentvolumes/pvc-80b98084-29a3-4a38-a96c-2f284042cf4f uid: 5321df93-5f21-4895-bafc-71538d50293a spec: accessModes: - ReadWriteOnce capacity: storage: 10Gi claimRef: apiVersion: v1 kind: PersistentVolumeClaim name: restore-test namespace: default resourceVersion: "474675088" uid: 80b98084-29a3-4a38-a96c-2f284042cf4f csi: driver: com.tencent.cloud.csi.cbs fsType: ext4 volumeAttributes: diskType: CLOUD_PREMIUM storage.kubernetes.io/csiProvisionerIdentity: 1604478835151-8081-com.tencent.cloud.csi.cbs volumeHandle: disk-gahz1kw1 nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: topology.com.tencent.cloud.csi.cbs/zone operator: In values: - ap-beijing-2 persistentVolumeReclaimPolicy: Delete storageClassName: cbs-csi volumeMode: Filesystem status: phase: Bound ``` ## 參考 - [Kubernetes CSI in Action: Explained with Features and Use Cases](https://medium.com/velotio-perspectives/kubernetes-csi-in-action-explained-with-features-and-use-cases-4f966b910774) - [CSI Volume Plugins in Kubernetes Design Doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md) >【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多幹貨!! ![](https://img2020.cnblogs.com/other/2041406/202012/2041406-20201217104541657-909706