Kasten k10 实战系列 03 – Kasten K10 存储集成功能

Kasten k10 实战系列 - 03 Kasten K10 存储集成功能

前言

随着 Kubernetes 中有状态应用程序的部署在云原生基础架构中的越发成熟,以及存储供应商对容器存储接口 CSI (Container Storage Interface )的迅速采用,目前 CSI 已经成为容器存储接口的事实标准,这其实给数据保护厂商来了新的机遇,今天我们来聊一下 Kasten 对 CSI的调用。

本文目录

  1. Kasten 的存储集成功能
  2. Kasten CSI 快照调用的效果
  3. Kasten CSI 快照调用知识储备
    • 3.1 容器存储接口基础知识(CSI)
    • 3.2. “In-Tree” 模式存在的问题
    • 3.3 Kubernetes CSI架构
  4. Kasten 的存储快照功能集成先决条件
    • 4.1. CAM 角色与权限规划
    • 4.2. 安装 cbs-csi 存储组件
    • 4.3. 建立 Storage Class
    • 4.4. 创建快照类
  5. 安装 K10 Kubernetes 的数据管理
  6. 总结
  7. 附录:Kasten 快照调用 Troubleshooting: 验证 CSI 存储组件的快照功能
    • 7.1 创建 PVC 用于快照测试
    • 7.2 为 PVC 创建快照
    • 7.3 从快照恢复数据到新 PVC

Kasten 实战系列导航

1. Kasten 的存储集成功能

如下图,Kasten 支持通过容器存储接口(CSI)进行存储集成,以便直接创建快照,从而提高备份、恢复的效率。

20210630105450

K10 支持两种集成方式,即直接集成和通过 CSI 集成。

直接集成 - Direct Provider Integration

K10支持与以下存储提供商的进行直接存储集成,以下存储提供商可以在 K10 中自动发现和配置:

  • Amazon Elastic Block Store (EBS)
  • Amazon Elastic File System (EFS)
  • Azure Managed Disks
  • Google Persistent Disk
  • Ceph (RBD)
  • Cinder-based providers on OpenStack
  • vSphere Cloud Native Storage (CNS)
  • Portworx

通过 CSI 集成 - Container Storage Interface (CSI)

除了直接集成存储提供商,K10 还支持通过容器存储接口 (Container storage Interface, CSI) 用卷快照操作。为了确保工作正常,请确保满足以下要求。

  • Kubernetes 为 v1.14.0及以上版本
  • Kubernetes 集群中已启用 VolumeSnapshotDataSource 特性
  • K8S 已经配置,支持卷快照的 CSI 驱动

2. Kasten CSI 快照调用的效果

让我们先来看看 K10 的快照调用效果。
在 Kasten 对应用进行管理时,可以直接为应用进行手动快照,以验证快照功能。

20210630111433

之后,马上我们就可以在 Dashboard 中,看到快照被创建的信息

20210630111631

从下图中,我们可以看到,mysql 应用绑定的,是 PVC pvc-241226b4-0440-4b76-843e-c33e1189cb51


$ kubectl get pvc -n mysql 
NAME    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql   Bound    pvc-241226b4-0440-4b76-843e-c33e1189cb51   10Gi       RWO            cbs-csi        4d19h

20210630112215

通过如下命令,我们发现承载 PVC 磁盘的信息, 通过查看磁盘快照链,我们就可以看到快照被创建的记录了

$ kubectl get pv pvc-241226b4-0440-4b76-843e-c33e1189cb51 -o yaml |grep volumeHandle 
    volumeHandle: disk-dkemfvjb

20210630112049

当然,我们也可以直接在 Policy 任务定义中,定义快照的使用,这样快照就可以自动运行了。

20210630113938

3. Kasten CSI 快照调用知识储备

看了上述过程您一定想我应该马上就能实现这些功能吧,实际的情况是,您必须要对存储的CSI StorageClass 与 SnapshotClass 进行应有的配置,此时此刻,让我们先冷静一下,想想我们需要哪些知识储备。

3.1 容器存储接口基础知识(CSI)

容器存储接口(CSI)是用于将任意块和文件存储系统暴露给诸如 Kubernetes 之类的容器编排系统(CO)上的容器化工作负载的标准。 使用CSI的第三方存储提供商可以编写和部署在 Kubernetes 中公开新存储系统的插件,而无需接触核心的 Kubernetes 代码。

为什么 CSI 会受到这样的认同呢,因为 CSI 能为容器编排引擎和存储系统间建立一套标准的存储调用接口,通过该接口能为容器编排引擎提供存储服务。比如自动化的卷扩展,快照等功能。 在 CSI 之前,K8S 里提供存储服务是通过一种称为 in-tree 的方式来提供,在腾讯云中默认的 CBS 存储类就是 in-tree 模式的。

# kubectl get sc   
NAME                PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
cbs                 cloud.tencent.com/qcloud-cbs   Delete          Immediate              false                  3d15h

3.2. “In-Tree” 模式存在的问题

“In-Tree” 的意思是这些存储类的代码是核心 Kubernetes 代码的一部分,并随核心 Kubernetes 核心文件一起发布,这样也带来了诸多的问题。比如,本来应该由各存储提供商自行维护的插件测试、维护的工作还要由 K8S 社区负责,插件间的相互影响,安全隐患等等。 由于这样的原因,我们在 Kasten 里也会推荐使用 CSI 的方式,因为这样 Kasten 就可以通过 CSI 做卷快照,快速获取数据用于备份了。

有关这部分知识的详细情况,请参考 Google David Zhu 的博客,非常值得一读。
Kubernetes 1.17 Feature: Kubernetes In-Tree to CSI Volume Migration Moves to Beta
https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-feature-csi-migration-beta/

3.3 Kubernetes CSI架构

Kubernetes 中 CSI 架构包含三个部分,Kubernetes Core、Kubernetes External Component、与 External Component,最后的这部分由第三方存储厂商开发,其将按照接口标准实现 CSI 的存储插件,主要有如下三类:

  • CSI Identity 负责认证插件的状态信息
  • CSI Controller  负责实际创建和管理 volumes
  • CSI Node 负责在 Kubernetes Node 上 volume 相关的功能

有关这部分知识的详细情况,请参考以下的博客,值得一读。
How to write a Container Storage Interface (CSI) plugin
https://arslan.io/2018/06/21/how-to-write-a-container-storage-interface-csi-plugin/

4. Kasten 的存储快照功能集成先决条件

4.1. CAM 角色与权限规划

确保如下策略在角色载体为 CCS 的 TKE_QCSRole中被关联

  • QcloudCBSFullAccess
  • CLBAutoPreAuthorization
  • QcloudAccessForTKERoleInOpsManagement
  • QcloudAccessForTKERole

20210627195218

4.2. 安装 cbs-csi 存储组件

通过腾讯云管理器,对存储插件的的安装非常方便,我们可以通过控制台直接进行组件的安装。在集群管理中,选择组件管理,新建

20210630065947

勾选 CBS
20210630070410

安装完成后,系统将显示 CSI 的 Controller 与 node 已经在 Running 状态

20210630080451

# 利用 kubectl 命令也具备相同效果
# kubectl get pods -n kube-system | grep cbs 
csi-cbs-controller-84ddd4c447-52z2g   6/6     Running   0          4d16h
csi-cbs-node-rtqrg                    2/2     Running   2          4d16h

4.3. 建立 Storage Class

在集群中新建 Storage Class

20210630101045

创建完成,可以看到有以下两个 Storage Class
20210630101232

将 cbs-csi 设置为 Default

在界面与命令行中都可以设置,注意要把之前的 cbs 存储类,default 设置为 false,再把 csb-csi default 设置为 Ture

20210630102526

通过 kubectl 命令行与 TKE的管理界面,都可以进行设置

$ kubectl patch storageclass <your-class-name> -p '{"metadata": {"annotations":{"storageclass.beta.kubernetes.io/is-default-class":"true"}}}'

$ kubectl get sc 
NAME                PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
cbs                 cloud.tencent.com/qcloud-cbs   Delete          Immediate              false                  4d18h
cbs-csi (default)   com.tencent.cloud.csi.cbs      Delete          WaitForFirstConsumer   true                   4d18h

有关这部分知识的详细情况,请参考以下链接 kubernetes 官方文档
改变默认 StorageClass
https://kubernetes.io/zh/docs/tasks/administer-cluster/change-default-storage-class/

4.4. 创建快照类

快照类的创建也是 K10 调用存储快照的前提条件,创建 VolumeSnapshotClass 使用以下 YAML,创建 VolumeSnapshotClass 对象。示例如下:

注意要 将 annotations k10.kasten.io/is-snapshot-class: "true" 加入到 VolumeSnapshotClass 的定义。


$ vim volumesnapshotclass.yaml

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
  annotations:
    k10.kasten.io/is-snapshot-class: "true"
  name: cbs-snapclass
driver: com.tencent.cloud.csi.cbs
deletionPolicy: Delete

执行以下命令,检查 VolumeSnapshotClass 是否创建成功。示例如下

$ kubectl apply -f  volumesnapshotclass.yaml
volumesnapshotclass.snapshot.storage.k8s.io/cbs-snapclass created

$ kubectl get volumesnapshotclasses       
NAME                      AGE
cbs-snapclass             24s

5. 安装 K10 Kubernetes 的数据管理

通过上述操作,我们建立了 符合 Kubernetes 上使用 CSI 标准的存储系统,但这只是个开始。为了真正利用数据的力量,我们现在将添加数据管理套件 K10 , 特别需要注意的是我们要在安装时,注明 CSI参数 --set global.persistence.storageClass=cbs-csi

安装 K10 非常简单,您应该会在 5 分钟或更短的时间内启动并运行!如果需要,您可以查看完整的文档,但只需按照这些说明开始。

helm install k10 k10-4.0.5.tgz --namespace kasten-io --set global.airgapped.repository=ccr.ccs.tencentyun.com/kasten-k10 \
  --set global.persistence.metering.size=20Gi \
  --set prometheus.server.persistentVolume.size=20Gi \
  --set global.persistence.catalog.size=20Gi \
  --set externalGateway.create=true \
  --set auth.tokenAuth.enabled=true \
  --set metering.mode=airgap \
  --set injectKanisterSidecar.enabled=true \
  --set global.persistence.storageClass=cbs-csi

如果在安装前没有调整,我们也可以在这时用命令行调整 VolumeSnapshotClass 的注释。请注意,就像 StorageClass r的 default 属性一样 ,只可以有一个 VolumeSnapshotClass 带有此注释的。我们还将在此处标记 **删除策略** 以保留快照。

$ kubectl annotate volumesnapshotclass cbs-csi k10.kasten.io/is-snapshot-class=true
$ kubectl patch volumesnapshotclass cbs-csi -p '{"deletionPolicy":"Retain"}' --type=merge


# 6. 总结

与 CSI 快照的集成,可以让备份恢复的数据管理工作变的更简单,同时也有机会适配更多的存储厂商,加大客户对存储基础架构的选择性。值得一提的是,快照是不能替代备份,Kasten 可以将这些快照导出到独立的对象存储来创建备份,实现 3-2-1-1-0 的保护,实现勒索病毒防护的目的。在下期的博客中我们将介绍 Kasten Kubestro 组件,这是一个可以帮助用户进行云存储选型的开源框架。敬请期待!欢迎大家扫描下方二维码申请 K10 免费试用,亲身动手试一试。

![20210628171302](https://mars-blog-1257130361.cos.ap-chengdu.myqcloud.com/20210628171302.png)

# 6. 附录:Kasten 快照调用 Troubleshooting: 验证 CSI 存储组件的快照功能

在我们日常运用的过程中经常会出现各种,快照无法使用的问题, 比如在跑 检测脚本时 k10_primer.sh 或是在使用CSI快照的时候,这时我们就需要进行 Troubleshooting,此时最好的方法就是手动将建立PVC,建立快照,用快照建立数据还原卷都走一遍。 以下是我们建立快照的过程,供您参考。

![20210630125455](https://mars-blog-1257130361.cos.ap-chengdu.myqcloud.com/20210630125455.png)

>  **有关这部分知识的详细情况,请参考以下链接,包括腾讯云手册与Github上的文档**
> [**使用 CBS CSI 插件对 PVC 进行备份与恢复**](https://cloud.tencent.com/document/product/457/50867)
> https://cloud.tencent.com/document/product/457/50867
> [**CBS CSI on github**](https://github.com/TencentCloud/kubernetes-csi-tencentcloud/blob/master/docs/README_CBS.md)
> https://github.com/TencentCloud/kubernetes-csi-tencentcloud/blob/master/docs/README_CBS.md

### 5.1 创建 PVC 用于快照测试

```yaml
# example-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: com.tencent.cloud.csi.cbs</code></pre>
<p>创建一个应用,绑定这个 PVC</p>
<pre><code class="language-yaml">kind: Pod
apiVersion: v1
metadata:
  name: csi-app
spec:
  containers:
    - name: csi
      image: busybox
      volumeMounts:
      - mountPath: "/data"
        name: csi-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: csi-volume
      persistentVolumeClaim:
        claimName: csi-pvc
</code></pre>
<p>可以看到这个应用已经启动, PVC 已经为 Bound 状态</p>
<pre><code>kubectl get pod     
NAME      READY   STATUS    RESTARTS   AGE
csi-app   1/1     Running   0          2m9s

# kubectl get pvc                                                        
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
csi-pvc   Bound    pvc-9282700f-2cef-49f2-be53-beb09dd50e57   10Gi       RWO            cbs-csi        106s</code></pre>
<h3>5.2 为 PVC 创建快照</h3>
<p>本文以 new-snapshot-demo 快照名为例创建 VolumeSnapshot。使用以下 YAML,创建 VolumeSnapshot 对象。示例如下</p>
<pre><code class="language-yaml">apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: new-snapshot-demo
spec:
  volumeSnapshotClassName: cbs-snapclass
  source:
    persistentVolumeClaimName: csi-pvc </code></pre>
<p>执行以下命令,查看 Volumesnapshot 和 Volumesnapshotcontent 对象是否创建成功,若 READYTOUSE 为 true,则创建成功。示例如下:</p>
<pre><code class="language-yaml">$ kubectl apply -f snapshot.yaml   
volumesnapshot.snapshot.storage.k8s.io/new-snapshot-demo created

$ kubectl get volumesnapshot   
NAME                AGE
new-snapshot-demo   18s</code></pre>
<p>执行以下命令,查看 Volumesnapshot 和 Volumesnapshotcontent 对象是否创建成功,若 READYTOUSE 为 true,则创建成功。示例如下:</p>
<pre><code># kubectl get volumesnapshotcontent  
NAME                                                                         AGE
snapcontent-4f4a1e32-557f-4704-adbb-8ee750c2f659                             30s

#kubectl get volumesnapshotcontent -o yaml snapcontent-f7bc8e23-88ee-421e-bac7-a56a1417ae69                                              </code></pre>
<p>执行以下命令,可以获取 Volumesnapshotcontent 对象的快照 ID,字段是 status.snapshotHandle(如下为 snap-rsk8v75j),可以根据快照 ID 在 容器服务控制台 确认快照是否存在。示例如下:</p>
<pre><code class="language-yaml">kubectl get volumesnapshotcontent -o yaml snapcontent-f7bc8e23-88ee-421e-bac7-a56a1417ae69    

~~~~
status:
  creationTime: 1625016814000000000
  readyToUse: true
  restoreSize: 10737418240
  snapshotHandle: snap-e89d6b8c
```  

![20210630094808](https://mars-blog-1257130361.cos.ap-chengdu.myqcloud.com/20210630094808.png)

### 5.3 从快照恢复数据到新 PVC

本文以上述 步骤 创建的 VolumeSnapshot 对象名称 new-snapshot-demo 为例,使用以下 YAML 从快照恢复数据到新的 PVC 中。示例如下:

```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
```

执行以下命令,可以查看 PVC 已经创建并绑定 PV,从 PV 中也可以查看到对应的 diskid(如下为 disk-ju0hw7no)。示例如下:

```yaml
$ kubectl get pvc

NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
csi-pvc        Bound    pvc-a702d1bd-11c7-44b4-b185-0cafe2707490   10Gi       RWO            cbs-csi        25m
restore-test   Bound    pvc-939c4659-6fbc-426b-8835-42d1071095af   10Gi       RWO            cbs-csi        2m37s

$ kubectl get pv pvc-939c4659-6fbc-426b-8835-42d1071095af -o yaml
~~~
      diskChargeType: POSTPAID_BY_HOUR
      diskType: CLOUD_PREMIUM
      storage.kubernetes.io/csiProvisionerIdentity: 1624606837377-8081-com.tencent.cloud.csi.cbs
    volumeHandle: disk-btgs7n6r
~~~    

注意:
如果 StorageClass 使用了拓扑感知(先调度 Pod 再创建 PV),即指定 volumeBindingMode: WaitForFirstConsumer,则需要先部署 Pod(需挂载 PVC)才会触发创建 PV(从快照创建新的 CBS 并与 PV 绑定)。

20210630100838

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注