使用Kasten K10进行k8s备份和恢复

747 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

介绍

官网地址:www.kasten.io/ 官方文档地址:docs.kasten.io/latest/inde…

K10不仅仅是一个Kubernetes备份产品,而是一个数据管理平台。 K10遵循期望状态(desired-state)模型,为我们提供声明式控制,并支持所有主要的Kubernetes发行版。 它带有一个直观的、基于GUI仪表板的管理工具,支持命令行。 它可以自动发现应用程序,包括那些跨卷或数据库的应用程序,简化了备份过程。 它还包括许多安全功能,通过企业级加密、IAM角色、RBAC、OpenID连接提供全面的端到端安全。 它还有多集群管理仪表板,在单一平台上处理多集群。 它还支持PostgreSQL、MongoDB、MySQL、Cassandra和AWS关系型数据库服务等数据服务。此外,它还支持众多厂商和云提供商的存储,包括NetApp、微软等。

file

安装

前提条件

  • 安装helm
  • 添加k10 repo
  • 有storageclass
helm repo add kasten https://charts.kasten.io/

file

  • 创建namespace
# 默认的是kasten-io
kubectl create namespace k10

file

安装k10

helm install k10 kasten/k10 --namespace=k10

file

这里pod会起不来,拉取不到镜像。下面是所需的镜像仓库地址。

docker.io/grafana
docker.io/jimmidyson
gcr.io/kasten-images
ghcr.io/kanisterio
quay.io/prometheus
registry.access.redhat.com/ubi8

使用docker playground下载镜像

登录docker playground,labs.play-with-docker.com/

添加实例

file

查看所需镜像

docker run --rm -it gcr.io/kasten-images/k10offline:5.5.2 list-images

拉取所需镜像

# 命令只能手动输入,不能复制粘贴
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock \
    gcr.io/kasten-images/k10offline:5.5.2 pull images

登录docker hub

docker login

添加tag并推送

docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock \
    -v ${HOME}/.docker:/root/.docker \
    gcr.io/kasten-images/k10offline:5.5.2 pull images --newrepo repo.example.com

file

file

重新安装

可以直接使用我的仓库地址,5.5.2和5.5.3的镜像都有。

helm pull kasten/k10
helm install k10 k10-5.5.2.tgz --namespace k10 --set global.airgapped.repository=wgh9626 --set global.persistence.storageClass=xxx

file

file

file

修改gateway svc为nodePort

k edit svc gateway -n k10

ports:
  - name: http
    nodePort: 30800
    port: 8000
    protocol: TCP
    targetPort: 8000
  type: NodePort

访问dashboard

ip:30800/k10/#/

file

输入邮箱和公司名,进入dashboard

file

可以看到Applications,有14个unmanaged,这个代表这些namespace中的应用没有备份策略,没有被k10管理。

file

备份

先看后面的备份报错解决,除非你想踩一遍我踩过的坑qaq

创建备份策略配置文件

选择设置,locations,new profile,可以指定s3,azure storage,google cloud storage,nfs,veeam repository。

file

这里选择s3 compatible,因为我的环境里已经有一个minio了。bucket name是k10,profile name设置为k10。

file

file

file

创建测试应用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        volumeMounts:
        - mountPath: /etc/test
          name: test
      volumes:
      - name: test
        persistentVolumeClaim:
          claimName: nginx-test

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-test
spec:
  accessModes:
    - ReadWriteOnce
	# 替换成你的StorageClass
  storageClassName: longhorn
  resources:
    requests:
      storage: 2Gi
---

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    name: http
    nodePort: 32356
  selector:
    app: nginx

file

file

创建测试页面

查看html目录位置

file

创建测试页面

cat test.html

<html>
This is test html
</html>

file

创建备份策略

设置备份时间,选择namespace,开启集群资源备份,创建snapshot并导出(export)备份到看minio bucket k10中。

file

可以看到test namespace已经在Compliant中了。

file

查看策略运行情况

file

点击可以查看详情

file

运行完成后

file

查看备份

minio上的备份:

file

file

longhorn上也会有个backup:(前提是longhorn上需要设置backup target)

file

开启Reports

file

开启后会自动创建一个策略:

file

查看备份数据使用:

file

grafana上查看备份恢复情况

file

恢复

删除test namespace

k delete -f nginx.yaml -n test
k edit pvc nginx-test -n test
# 删除下面的finalizers
finalizers:
  - snapshot.storage.kubernetes.io/pvc-as-source-protection
k edit volumesnapshots k10-csi-snap-5dwdgbkzkb4t62dl -n test
# 删除下面的finalizers
finalizers:
  - snapshot.storage.kubernetes.io/volumesnapshot-bound-protection
k delete volumesnapshots k10-csi-snap-5dwdgbkzkb4t62dl -n test
k delete ns test

file

test namespace已删除。

file

选择restore

file

查看详情

file

可以选择恢复到新的namespace,需要点create,这里没有创建;可以选择在恢复后的动作(hook)需要先设置blueprint。也可以更改元数据信息,比如修改StorageClass name或者修改镜像名(Apply transforms to restored resources)。

file

可以选择恢复的内容

file

点击restore,确认恢复

file

已恢复

file

查看恢复情况

file

备份报错解决

longhorn StorageClass

报错信息: Failed to find VolumeSnapshotClass with k10.kasten.io/is-snapshot-class=true annotation in the cluster

file

添加storageClass annotation

kubectl get volumesnapshotclass longhorn
kubectl annotate volumesnapshotclass longhorn k10.kasten.io/is-snapshot-class=true
kubectl get volumesnapshotclass longhorn -o yaml

file

添加后仍然报错: Failed to check and update snapshot content: failed to take snapshot of the volume, pvc-150c08c4-92e4-4975-a59c-afa09a4b3964: "timestamp: nil Timestamp" file

file

搜索相关文档,是longhorn存储的问题: github.com/longhorn/lo…

需要给VolumeSnapshotClass添加annotation:type: snap parameters.type: snap

apiVersion: snapshot.storage.k8s.io/v1
deletionPolicy: Delete
driver: driver.longhorn.io
kind: VolumeSnapshotClass
metadata:
  annotations:
    k10.kasten.io/is-snapshot-class: "true"
    type: snap
    parameters.type: snap
  name: longhorn

longhorn添加backup target,具体步骤参考这里

file

local-path storageclass

报错不支持: Volume Snapshots are not supported for this storage provider.Try K10's Generic Storage Backup method file

升级k10

helm upgrade k10 k10-5.5.2.tgz --set injectKanisterSidecar.enabled=true --set-string injectKanisterSidecar.namespaceSelector.matchLabels.k10/injectKanisterSidecar=true --set global.airgapped.repository=wgh9626 -n k10

到docker playground中拉取推送ghcr.io/kanisterio/kanister-tools:0.85.0到dockerhub,可以直接使用我的镜像

docker pull wgh9626/kanister-tools:0.85.0

重新创建测试应用,我直接使用的rancher应用商店中的mysql

k create ns mysql
k label ns mysql k10/injectKanisterSidecar=true

file

查看pod内容器已自动注入了sidecar。

file

file

mysql的deployment也自动加了annotations:k10.kasten.io/forcegenericbackup: "true"

file

创建测试数据

k get secret mysql -n mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d

mysql -u root -p
create database test;
use test;
CREATE TABLE Persons (Id_P int,LastName varchar(255),FirstName varchar(255),Address varchar(255),City varchar(255));
show tables;
INSERT INTO Persons VALUES ('1', 'qq', 'aa', 'hz', 'zj');
INSERT INTO Persons VALUES ('2', 'ww', 'ss', 'hz', 'zj');
INSERT INTO Persons VALUES ('3', 'ee', 'dd', 'hz', 'zj');
select * from Persons;

file

创建备份 file

仍然报错:"Failed to backup data","function":"kasten.io/k10/kio/kanister/function.(*backupDataFunc).Exec","linenumber":120,"file":"kasten.io/k10/kio/kanister/function/backup_data.go:120","cause":{"message":"Failed to create and upload backup","function":"kasten.io/k10/kio/kanister/function.backupData","linenumber":200,"file":"kasten.io/k10/kio/kanister/function/backup_data.go:200","cause":{"message":"Failed to exec command in pod: command terminated with exit code 1"

file

查找相关文档: community.veeam.com/kasten-k10-…

可以通过查看kanister-svc pod的日志来查看备份失败更详细的原因

file

报错原因是minio存储空间不足无法备份了。删除minio的一些数据,重新备份,备份成功。

file

登录数据库删除person表。

file

登录k10恢复

file

可以看到k10创建了2个pod来恢复:affinity-pvc-group,restore-data

file

登录mysql,查看数据已恢复。

file

ceph StorageClass

如果sc是ceph的话,需要先创建一个Infrastructure Profiles。

image.png

创建profile,name为ceph,type选择ceph,monitor中填写ceph mon的地址。 file

填写ceph pool的名字,ceph client user,keyring。

image.png

file

image.png

parsing time "" as "Mon Jan _2 15:04:05 2006" : cannot parse "" as "Mon"

file

这个是创建备份时没有选择备份过期时间导致的。重新创建一个备份选择过期时间即可。

image.png