kasten

TLDR:使用Veeam Kasten对Kubernetes工作负载进行应用级的备份和还原。

听上去有点像是Veeam的软文,事实上只是最近用BitMagnet搜刮DHT资源的时候偶然间发现了Veeam Backup & Replication v12的资源。VBR v11之初的时候就从原厂得知veeam收购了一家做k8s备份的厂家,v12的时候把这个产品融合到了VBR中,尽管感觉集成得相当牵强。另外v12增加了对Proxmox虚拟化的支持,对homelab用户又是一个不错的消息,如果想要一个备份平台管理所有备份资产的话。虽然自家的Proxmox Backup Server新版本也推出了许多实用的功能。

为什么要备份K8S

其实k8s的业务平面的数据保护之前一直觉得是一个伪需求,资源文件会存在CD仓库,二进制程序在镜像仓库,结构化数据在数据库,需要持久化的文件在对象存储里或者FileStorage服务器里,容器平台更多的是无状态应用,要备份的也就只有PV里的持久化数据。PV的数据完整性完全可以依赖CSI Driver和后端存储来保证,比如ceph的快照和多站点容灾机制。

怪不得Kasten和Kanister把自己定义成应用管理工具,更多是用来迁移或者当基础设施受灾时快速恢复应用。随着家里k8s集群上承载的客户应用越来越多,似乎要开始考虑应用的RTO问题了,于是打开了k8s备份这个兔子洞。

方案选择

  • CEPH RBD快照导出/CEPHFS使用文件系统同步方案
  • velero
  • kasten

其中CEPH集群原生支持将块设备的快照导出,甚至可以在两个CEPH集群之间异步同步RBD镜像,ceph rbd提供的PVC可以使用k8s external-snapshotter创建ceph rbd快照然后用ceph cli导出。CEPHFS可以用文件系统级别的同步或者备份方案。只是大部分操作需要自行编写脚本实现自动化,易用性不高。

velero和kasten的定位类似,都能对k8s资源和PV进行备份,前者更是开源的。不过前者没有原生图形化界面,只能通过创建CRD控制。kasten相对更加完善,毕竟是商业化产品,并且提供小于5节点的CE版本。对于备份存储支持类型,后者除了S3外,还可以用VBR的Repository,更加符合当前的备份工作流。

部署

kasten对PV的备份也是通过kubernetes-csi/external-snapshotter创建快照然后导出快照实现的,所以也需要csi和storage provisioner支持快照和快照导出。在我的环境下,使用k8s-1.30、ceph-19.2.2、ceph-csi-3.14.2、external-snapshotter-release-8.2经验证无兼容性问题。

按照文档提示,ceph-csi的snapshotter sidecar版本最好和external-snapshotter的controller和crd保持一致。

安装snapshot controller和crd

git clone https://github.com/kubernetes-csi/external-snapshotter/
cd ./external-snapshotter
git checkout release-8.2
kubectl kustomize client/config/crd | kubectl create -f -
kubectl -n kube-system kustomize deploy/kubernetes/snapshot-controller | kubectl create -f -

deploy/kubernetes/csi-snapshotter如果不用hostpath无需安装,ceph-csi中已经包含了snapshotter的sidecar。

如果没有老的应用依赖v1beta1版本的API也不用部署Webhook conversion组件。

部署VolumeSnapshotClass类

参考各自的csi文档配置,ceph-csi需要添加ceph集群的鉴权信息。kasten使用还需要额外添加k10.kasten.io/is-snapshot-class的annotations。

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-rbdplugin-snapclass
  annotations:
    k10.kasten.io/is-snapshot-class: "true"
driver: rbd.csi.ceph.com
deletionPolicy: Delete
parameters:
  clusterID: "a94d2d38-3302-11ef-94fe-351d24676c48"
  csi.storage.k8s.io/snapshotter-secret-name: "csi-rbd-secret"
  csi.storage.k8s.io/snapshotter-secret-namespace: "default"

验证external-snapshotter可用

这时候已经可以通过手动创建VolumeSnapshot资源来测试打镜像了。

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: rbd-demo-snapshot
  namespace: default
spec:
  volumeSnapshotClassName: csi-rbdplugin-snapclass
  source:
    persistentVolumeClaimName: rbd-pvc

正常的话已经可以看到对象的ReadyToUse状态为True。

ceph dashboard可以看到生成了新的rbd image设备。

最大的麻烦

这里遇到了本次困扰最久的问题,VolumeSnapshot创建触发VolumeSnapshotContent后,状态迟迟没有Ready。观察snapshot-controller组件日志提示content完成bound之后csi-rbdplugin-provisioner/csi-snapshotter一致没有收到创建快照的请求。

怀疑过external-snapshotter的API版本,因为csi-rbdplugin-provisioner/csi-snapshotter有尝试使用v1beta1版本的API。

怀疑过ceph-csi安装不完整,之前只安装了rbd和cephfs相关功能。

怀疑过版本兼容性,尝试了不同版本的external-snapshotter。

最终问题指向了ceph-csi版本,原来是当初安装的canary金丝雀版本的特性不完整,升级ceph-csi版本后就好了。顺手把ceph-csi升级到了k8s-1.30的最后一个支持版本3.14,一切终于变得丝滑了起来。

安装kasten

# precheck
curl -s https://docs.kasten.io/downloads/8.0.6/tools/k10_primer.sh | bash /dev/stdin csi -s csi-rbd-sc

# helm安装kasten
helm repo add kasten https://charts.kasten.io --force-update && helm repo update
helm show values kasten/k10 > values.yaml
helm install k10 kasten/k10  --values values.yaml --namespace=kasten-io

veeam连接kasten

创建dashboardbff-svc用户token后填入VBR连接,gateway用户不行。

kubectl create token dashboardbff-svc -n kasten-io --duration=9999h

要注意Veeam连接Kasten需要使用https端点,因此还需要创建ingress。

这时候就会发现大部分操作还是会调用浏览器进入Kasten后台进行操作,VBR几乎只用来同步状态信息。好家伙,这是集成了个寂寞。

备份还原实验

k10的思想是备份整个namespace以及所用到的集群级资源以便快速恢复整个应用,也可以用过滤器指定要备份的资源。还可以通过蓝图集成Kanister在执行备份的前后对需要考虑数据一致性的应用执行pre和post操作。

选上快照导出的话可以自动在打完快照之后将快照导出至NFS/SMB、VBR Repository或者公有云对象存储。然而快照导出分成元数据和PV快照两部分,元数据却不支持导出至VBR的存储池,明明是自家产品却显得那么拧巴。

如果在运行快照的时候收到类似message: volumesnapshotclasses.snapshot.storage.k8s.io not found的报错,是因为你需要按照文档在pvc所用的sc添加annotations,明明在precheck脚本已经通过确保快照是正常生成的。

k10.kasten.io/volume-snapshot-class: [VolumeSnapshotClassName]

如果在执行导出快照时提示你的csi不支持快照导出的报错,也可能是因为你需要按照文档给sc添加annotations而不一定是csi本身不支持。

k10.kasten.io/sc-supports-block-mode-exports: 'true'

除了以上这些,还有各种配置过程中磕磕绊绊的问题,只有去细细阅读文档才发现有一个配置要做。实话说不管是Dashboard的菜单设计还是文档编排逻辑都不是那么清晰。

完成快照和快照导出之后,测试了删除部分资源、删除整个namespace,通过快照、通过导出的备份进行还原,Kasten都完成得不错。

S3中元数据的备份文件

VBR存储池中块设备备份文件

关于快照导出,要知道快照!=备份。快照元数据存储在kasten的pv中,pv快照存储在ceph rbd中,当kasten或者ceph集群本身遭到破坏的时候,就只有第三方存储介质里的备份才能拯救了。

在恢复导出的备份时,Kasten先会创建一个临时PVC,由临时容器把备份恢复到临时PVC中,然后修改成真实PVC挂载给原pod。

后记

结论是功能本身没问题但是产品并没有打磨得非常成熟。易用性仍旧没有做到像消费级软件那样,如果想要胜任备份管理员的职责,Veeam会告诉你,“去交钱参加原厂认证培训去吧”,花大价钱去弄懂一些隐晦又反人类的系统操作设计逻辑,换一张证书,各大备份软件厂商都是这样。但是尽管如此,Veeam还是属于容易上手的一类备份产品。