Kasten k10 云原生存储适配系列 01 - 结合 XSKY CSI 容器存储解决方案保护云原生应用
内容提要
发展云原生生态圏是 Veeam 的又一重要战略,以 Kasten by Veeam 为圆心,这个战略又分为三个重要的组成部分,公有云厂商、K8S 分发版本和云原生存储厂商。云原生的领域中,与云原生生态所适配的存储又成为大家所关注的热点。Veeam China 在中国的云原生生态战略部局中也积极的与国内多家云原生存储厂商合作。XSKY CSI 容器存储解决方案,已经助力多家企业实现云原生存储转型,是国内率先通过 K8S CSI 认证的 SDS 厂商与国内加入 CNCF Landscape 全景图的 SDS 厂商之一。今天我们要讲解的是如何在与XSKY CSI 容器存储解决方案结合保护云原生应用。
- 前言
- Kasten 与 XSKY
- 测试环境配置检查
3.1 检查 Nodes 及其资源
3.2 检查CSI Driver是否部署成功
3.3 检查 K8S api-versions - 配置测试环境存储与快照类
4.1 配置 storageclass
4.2 配置 volumesnapshotclasss - 用 Kasten kubestr 对云原生存储进行评测
5.1 Kubestr 的安装
5.2 检查 kubenetes 环境 与 Storage Provisioners
5.3 进行快照功能测试
5.4 进行简单的性能测试 - 安装 Kasten K10 到 K8S 集群
- 结合 XSKY CSI 容器存储解决方案保护云原生应用测试
7.1 测试应用 mysql 的安装
7.2 应用程序发现
7.3 应用程序的备份与恢复
7.3.1 建立 MySQL 数据集
7.3.2 创建 Policy 保护 MySQL 应用
7.3.3 模拟灾难 删除 MySQL 数据
7.3.4 还原 MySQL 数据
7.3.5 查看还原后的 MySQL 数据 - 利用 Xsky 对象存储对云原生应用数据进行长期保留
8.1 创建 Location Profile
8.2 编辑 Policy 设定将快照备份导出到 xsky 对象存储
8.3 点击 Run Once 运行新规则
8.4 查看 数据备份进行程
8.5 利用对象存储库的备份集进行恢复
8.6 从 k8s 上确认数据已经恢复
8.7 从 Kasten K10 上观察存储库的数据使用情况
8.8 利用存储桶复制的方法避免人为错误 - 总结
- 参考链接
1. 背景与验证目标
1.1 背景
发展云原生生态圏是 Veeam 的又一重要战略,以 Kasten by Veeam 为圆心,这个战略又分为三个重要的组成部分,公有云厂商、K8S 分发版本和云原生存储厂商。云原生的领域中,与云原生生态所适配的存储又成为大家所关注的热点。Veeam China 在中国的云原生生态战略部局中也积极的与国内多家云原生存储厂商合作。XSKY CSI 容器存储解决方案,已经助力多家企业实现云原生存储转型,是国内率先通过 K8S CSI 认证的 SDS 厂商与国内加入 CNCF Landscape 全景图的 SDS 厂商之一。今天我们要讲解的是如何在与XSKY CSI 容器存储解决方案结合保护云原生应用。
1.2 验证目标与达成效果
在本次验证场景中,我们将结合 XSKY CSI 容器存储解决方案保护云原生应用的方式。
- 利用 Kubestr 对云原生存储进行评测
- 利用 K10 对存储 CSI API 进行调用生成快照,达成最快速的 RPO 与 RTO的备份与恢复
- 利用 XSKY 对象存储,将快照数据导出到对象存储桶上,实现了异地容灾与数据长期保留
达成效果:
- 利用 XSKY CSI 快照,在本地 Kubenetes 环境,云原生应用的快速备份与恢复(利用CSI快照)
- 利用 XSKY 对象存储,在本地形成长期保留
- 利用 Kasten K10 直接将数据容灾到远端,或利用 XSKY 对象存储实现存储桶的复制,实现 3-2-1-1-0 的数据保护。
2. Kasten 与 XSKY
Kasten K10
Kasten 是 Veeam 在 Kubernetes 平台的数据管理解决方案,通过部署 Kasten K10 企业可以安全地备份和还原、执行灾难恢复以及迁移云原生的应用。Kubernetes 集群资源和持久卷等存储资源。解决用户备份、灾难恢复、迁移过程中的数据管理问题,提高云原生环境数据管理的便捷性,帮助用户降低灾备成本,提高生产执行效率。
XSKY 星辰天合
XSKY 星辰天合作为国内率先通过 K8s CSI 认证的 SDS 厂商,同时也是加入 CNCF Landscape 全景图的 SDS 厂商之一, 针对企业云原生业务提出了基于软件定义存储(SDS)的容器存储解决方案。解决了需要敏捷性、并能够同时访问多个应用程序 容器的数据流动性问题,同时还提供包括快照、克隆和复制等高级存储特性。
-
标准接口,统一存储
实现标准的 K8s CSI 接口,无缝支持 K8s 生态,支持 iSCSI 和 NFS 两种接口,实现块和文件的统一存储。 -
存算分离,稳定可靠
将计算和存储分离,实现资源隔离,可独立对存储集群进行扩容;基于数千个企业级生产案例的最佳实践,XSKY 星辰天合分布式存储为容器平台提供稳定可靠的保障。 -
性能卓越,特性丰富
可根据应用需要提供全 SSD、混合盘以及全 HDD 等存储资源,通过 XSKY SDS IO 全路径的性能优化能力,获得卓越性能;除了支持裸设备、卷扩容、卷克隆、卷快照和QoS等基础特性,也支持延展集群和 MPIO 等高级特性。
随着 Kubernetes 在企业 IT 基础架构体系中的采用日渐增多,可供用户使用的持久化存储产品也越来越多。CSI(容器存储接口)的引入使存储提供商能够轻松开发驱动程序。事实上今天有大约 100 种不同的 CSI 驱动程序可用,这使得存储的选型变得越发困难。如何为基础架构选择理想的存储提供商,已经成为了运维主管们的一个新型挑战。而传统的存储选型方法对于云原生架构又不一定合适,这时 Kubestr 就应运而生了。
3. 测试环境配置检查
3.1 检查 Nodes 及其资源
测试环境如下,由三个 Nodes 组成, 一个Master 与 两个 Worker
$ kubectl get no -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
wrc4 Ready master 40h v1.19.9 10.252.2.223 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
wrc5 Ready <none> 38h v1.19.9 10.252.3.230 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
wrc6 Ready <none> 38h v1.19.9 10.252.3.232 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
$ kubectl describe nodes | grep -E 'Hostname|cpu|memory'
Hostname: wrc4
cpu: 4
memory: 16378612Ki
cpu: 4
memory: 16276212Ki
cpu 650m (16%) 100m (2%)
memory 50Mi (0%) 50Mi (0%)
MemoryPressure False Mon, 11 Oct 2021 05:57:12 +0800 Sat, 09 Oct 2021 14:07:51 +0800 KubeletHasSufficientMemory kubelet
has sufficient memory available
Hostname: wrc5
cpu: 4
memory: 16247528Ki
cpu: 4
memory: 16145128Ki
cpu 634m (15%) 2300m (57%)
memory 2362Mi (14%) 1874Mi (11%)
MemoryPressure False Mon, 11 Oct 2021 05:57:38 +0800 Sat, 09 Oct 2021 14:07:57 +0800 KubeletHasSufficientMemory kubelet
has sufficient memory available
Hostname: wrc6
cpu: 4
memory: 16378604Ki
cpu: 4
memory: 16276204Ki
cpu 430m (10%) 100m (2%)
memory 784Mi (4%) 390Mi (2%)
3.2 检查CSI Driver是否部署成功
安装driver,所有pod状态为running,部署成功。 关于 Xsky CSI Driver 部署,请联系Xsky专业人员。
NAME READY STATUS RESTARTS AGE
csi-sidecar-iscsi-attacher-5b8f7cd845-67ff7 1/1 Running 0 37h
csi-sidecar-iscsi-attacher-5b8f7cd845-jb9mx 1/1 Running 0 37h
csi-sidecar-iscsi-provisioner-86d4c4df75-5hgxv 1/1 Running 0 37h
csi-sidecar-iscsi-provisioner-86d4c4df75-zwzl8 1/1 Running 0 37h
csi-sidecar-iscsi-resizer-86c75b544d-nk752 1/1 Running 0 37h
csi-sidecar-iscsi-resizer-86c75b544d-w4kgh 1/1 Running 0 37h
csi-snapshotter-784446b849-npvbn 1/1 Running 0 37h
csi-snapshotter-784446b849-q6sv2 1/1 Running 0 37h
csi-xsky-iscsi-driver-lv8q9 2/2 Running 0 37h
csi-xsky-iscsi-driver-s9tjv 2/2 Running 0 37h
kubestr-csi-cloned-pod2lkgc 1/1 Running 0 18h
kubestr-csi-original-podt7mtd 1/1 Running 0 18h
snapshot-controller-6bc478bfbf-657nz 1/1 Running 0 37h
snapshot-controller-6bc478bfbf-9pwfl 1/1 Running 0 37h
3.3 检查 K8S api-versions
版本最低要求为 v1beta1
[root@wrc4 ~]# kubectl api-versions |grep storage
snapshot.storage.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
4. 配置测试环境存储与快照类
4.1 配置 storageclass
1. 设置存储类为默认
$ kubectl patch storageclass iscsi-sc -p '{"metadata": {"annotations":{"storageclass.beta.kubernetes.io/is-default-class":"true"}}}'
2. 设置存储类为默认
$ kubectl annotate storageclass iscsi-sc k10.kasten.io/volume-snapshot-class=csi-snapclass
storageclass.storage.k8s.io/iscsi-sc annotated
[root@wrc4 ~]# kubectl get sc iscsi-sc -o yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
k10.kasten.io/volume-snapshot-class: csi-snapclass
storageclass.beta.kubernetes.io/is-default-class: "true"
parameters:
accessPaths: csi-ap
csi.storage.k8s.io/provisioner-secret-namespace: default
fsType: xfs
pool: pool-30b37baf9dcf43b0bdfbc9aa67597a52
xmsServers: 10.252.3.220,10.252.3.227,10.252.3.236
provisioner: iscsi.csi.xsky.com
reclaimPolicy: Delete
volumeBindingMode: Immediate
4.2 配置 volumesnapshotclasss
1. 设置快照类为注释提示 K10 进行调用
kubectl annotate volumesnapshotclass csi-snapclass \
k10.kasten.io/is-snapshot-class=true
[root@wrc4 ~]# kubectl get volumesnapshotclass csi-snapclass -o yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
deletionPolicy: Delete
driver: iscsi.csi.xsky.com
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
parameters:
flatten: "true"
use: "true"
5. 用 Kasten kubestr 对云原生存储进行评测
Kubestr 是一个简单的轻量级工具,用于评估集群中的存储选项。它可以帮助您 发现、验证和评估 您的 kubernetes 云原生存储,以明确当前配置的状态与存储能力是否满足应用的要求。当比较跨多个集群、云平台与存储选项的性能时,还可以通过切换 Kubeconfig 使其跨多个集群运行。
5.1 Kubestr 的安装
下载 Kubestr, 从如下链接可以直接下载您所需要的 Kubestr 版本
https://github.com/kastenhq/kubestr/releases/tag/v0.4.17
用 wget 可以直接获取 Kubestr 软件包, 并解包
# wget https://github.com/kastenhq/kubestr/releases/download/v0.4.17/kubestr-v0.4.17-linux-amd64.tar.gz
# tar -zxvf kubestr-v0.4.17-linux-amd64.tar.gz
LICENSE
README.md
kubestr
5.2 检查 kubenetes 环境 与 Storage Provisioners
[root@wrc4 ~]# ./kubestr
**************************************
_ ___ _ ___ ___ ___ _____ ___
| |/ / | | | _ ) __/ __|_ _| _ \
| ' <| |_| | _ \ _|\__ \ | | | /
|_|\_\\___/|___/___|___/ |_| |_|_\
Explore your Kubernetes storage options
**************************************
Kubernetes Version Check:
Valid kubernetes version (v1.19.9) - OK
RBAC Check:
Kubernetes RBAC is enabled - OK
Aggregated Layer Check:
The Kubernetes Aggregated Layer is enabled - OK
Available Storage Provisioners:
iscsi.csi.xsky.com:
This might be a CSI Driver. But it is not publicly listed.
Storage Classes:
* iscsi-sc
To perform a FIO test, run-
./kubestr fio -s <storage class>
5.3 进行快照功能测试
目的是简单快速的进行快照功能的验证,在验证过程中,kubestr 会创建一个Pod,在其上绑定PVC,再对其进行 Clone 操作。
$ ./kubestr csicheck -s iscsi-sc -v csi-snapclass
Creating application
-> Created pod (kubestr-csi-original-pod9swkn) and pvc (kubestr-csi-original-pvc7c7gd)
Taking a snapshot
-> Created snapshot (kubestr-snapshot-20211011062007)
Restoring application
-> Restored pod (kubestr-csi-cloned-podtd5j6) and pvc (kubestr-csi-cloned-pvc7g8qw)
Cleaning up resources
CSI checker test:
CSI application successfully snapshotted and restored. - OK
测试过程中,我们可以查看 Pod 和绑定的 PVC
$ kubectl get po | grep kubestr
NAME READY STATUS RESTARTS AGE
kubestr-csi-cloned-podtd5j6 1/1 Running 0 53s
kubestr-csi-original-pod9swkn 1/1 Running 0 93s
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
kubestr-csi-cloned-pvc7g8qw Bound pvc-c544139c-3dd2-4a97-a032-6fd5420ceef7 1Gi RWO iscsi-sc 53s
kubestr-csi-original-pvc7c7gd Bound pvc-e8259c05-2311-4173-aa3b-1ffa85894925 1Gi RWO iscsi-sc 93s
5.4 进行简单的性能测试
性能测试的默认用例将涉及如下场景,同时默认的存储性能测试会创建一个100G的卷, 如果您希望调整测试场景与卷大小,可使用 -f 来写配置文件, -z 选项来指定卷的大小。详细情况见如下的帮助提示。
- blocksize=4K filesize=2G iodepth=64 rw=randread
- blocksize=4K filesize=2G iodepth=64 rw=randwrite
- blocksize=128K filesize=2G iodepth=64 rw=randread
- blocksize=128k filesize=2G iodepth=64 rw=randwrite
[root@wrc4 ~]# ./kubestr fio -s iscsi-sc
PVC created kubestr-fio-pvc-sql82
Pod created kubestr-fio-pod-8t9jj
Running FIO test (default-fio) on StorageClass (iscsi-sc) with a PVC of Size (100Gi)
Elapsed time- 59.248387664s
FIO test results:
FIO version - fio-3.20
Global options - ioengine=libaio verify=0 direct=1 gtod_reduce=1
JobName: read_iops
blocksize=4K filesize=2G iodepth=64 rw=randread
read:
IOPS=593.084778 BW(KiB/s)=2388
iops: min=128 max=1080 avg=597.233337
bw(KiB/s): min=512 max=4320 avg=2389.300049
JobName: write_iops
blocksize=4K filesize=2G iodepth=64 rw=randwrite
write:
IOPS=284.114105 BW(KiB/s)=1153
iops: min=14 max=454 avg=285.799988
bw(KiB/s): min=56 max=1816 avg=1143.633301
JobName: read_bw
blocksize=128K filesize=2G iodepth=64 rw=randread
read:
IOPS=458.349823 BW(KiB/s)=59201
iops: min=128 max=720 avg=461.399994
bw(KiB/s): min=16384 max=92231 avg=59087.199219
JobName: write_bw
blocksize=128k filesize=2G iodepth=64 rw=randwrite
write:
IOPS=281.200745 BW(KiB/s)=36523
iops: min=123 max=443 avg=284.933319
bw(KiB/s): min=15840 max=56718 avg=36494.300781
Disk stats (read/write):
sdn: ios=18161/9887 merge=32/41 ticks=1011952/1608942 in_queue=2634984, util=99.491051%
- OK
6. 安装 Kasten K10 到 K8S 集群
1. 获取 Helm Chart 供本地使用
# 添加 Kasten Helm charts 存储库
$ helm repo add kasten https://charts.kasten.io/
$ helm repo list
NAME URL ls
kasten https://charts.kasten.io/
$ helm repo update
# 以下这条命令会把 k10-4.0.x.tgz 包下载下来,如果不加任何参数,则会下载最新的版本
# 在Air Gapped 的环境中安装时,可以先行下载再使用。
$ helm fetch kasten/k10 --version=4.0.9
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kasten" chart repository
Update Complete. ⎈Happy Helming!⎈
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kasten" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ?Happy Helming!?
2.建立名空间
$ kubectl create namespace kasten-io
namespace/kasten-io created
3. 安装 Kasten K10
# helm install k10 k10-4.0.9.tgz --namespace kasten-io --set global.airgapped.repository=ccr.ccs.tencentyun.com/kasten-k10 \
--set auth.basicAuth.enabled=true \
--set injectKanisterSidecar.enabled=true \
--set auth.basicAuth.htpasswd='mars:$apr1$Cgu1sGVZ$w/8aLHZkVT73OqYZ06C0v.' \
--set metering.mode=airgap \
--set global.persistence.storageClass=iscsi-sc
目前在不同的 K8S 环境下部署 K10 有很多参数需要设置,此时我们需要查阅部署参数。
查看 Kasten Helm 部署的参数
Complete List of K10 Helm Options
https://docs.kasten.io/latest/install/advanced.html
4. 确认 Kasten K10 Pod 及 Service 的部署情况
[root@wrc4 ~]# kubectl get po -n kasten-io
NAME READY STATUS RESTARTS AGE
aggregatedapis-svc-dd848f44f-csx2h 1/1 Running 0 50m
auth-svc-6b56c947c6-442t7 1/1 Running 0 50m
catalog-svc-96d47984-b6tz5 2/2 Running 0 50m
config-svc-6b89d457f7-hxdvg 1/1 Running 0 50m
crypto-svc-bffdcf7f9-p4psk 2/2 Running 0 50m
dashboardbff-svc-5959979b8b-8xqdl 1/1 Running 0 50m
executor-svc-85ddfc4b8-lg7k4 2/2 Running 0 50m
executor-svc-85ddfc4b8-nrbbx 2/2 Running 0 50m
executor-svc-85ddfc4b8-xnt75 2/2 Running 0 50m
frontend-svc-74c9cf8bfd-8qqn8 1/1 Running 0 50m
gateway-6479f6ffd5-zv4xh 1/1 Running 0 50m
jobs-svc-7bf844cb76-nnqjn 1/1 Running 0 50m
kanister-svc-7c677c45c8-6cjrg 1/1 Running 0 50m
logging-svc-8d8ff9ddf-76h9s 1/1 Running 0 50m
metering-svc-58bdbbdc4-bwn98 1/1 Running 0 50m
prometheus-server-7c5bf49684-2srvm 2/2 Running 0 50m
state-svc-7bd949fd66-tgxtk 1/1 Running 0 50m
[root@K8S-1 ~]# kubectl get svc -n kasten-io
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
aggregatedapis-svc ClusterIP 10.109.189.72 <none> 443/TCP 81m
auth-svc ClusterIP 10.100.229.3 <none> 8000/TCP 81m
catalog-svc ClusterIP 10.106.112.188 <none> 8000/TCP 81m
config-svc ClusterIP 10.100.87.2 <none> 8000/TCP 81m
crypto-svc ClusterIP 10.101.73.63 <none> 8000/TCP,8001/TCP 81m
dashboardbff-svc ClusterIP 10.101.112.30 <none> 8000/TCP 81m
executor-svc ClusterIP 10.104.106.121 <none> 8000/TCP 81m
frontend-svc ClusterIP 10.96.173.65 <none> 8000/TCP 81m
gateway ClusterIP 10.102.193.96 <none> 8000/TCP 81m
gateway-admin ClusterIP 10.104.123.173 <none> 8877/TCP 81m
jobs-svc ClusterIP 10.100.178.7 <none> 8000/TCP 81m
kanister-svc ClusterIP 10.105.235.55 <none> 8000/TCP 81m
logging-svc ClusterIP 10.109.198.29 <none> 8000/TCP,24224/TCP,24225/TCP 81m
metering-svc ClusterIP 10.106.196.149 <none> 8000/TCP 81m
prometheus-server ClusterIP 10.111.79.75 <none> 80/TCP 81m
prometheus-server-exp ClusterIP 10.105.225.23 <none> 80/TCP 81m
state-svc ClusterIP 10.109.191.147 <none> 8000/TCP 81m
5. 访问 K10 控制台
通过查看 K8S Service,我们可以看到 K10的 ingress 配置,其中的 Gateway-ext,查看 访问 K10的 IP地址,访问 http://10.252.3.229:31940/k10/#
# 暴露 gateway service 给 NodePort
$ kubectl expose service gateway -n kasten-io --type=NodePort --name=gateway-nodeport
service/gateway-nodeport exposed
# 查看 NodePort端口
$ kubectl get svc -n kasten-io gateway-nodeport
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gateway-nodeport NodePort 10.105.160.17 <none> 8000:31940/TCP 2m35s
# 查看 Node IP
[root@wrc4 ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
wrc4 NotReady master 24h v1.19.9 10.252.2.223 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
wrc5 Ready <none> 22h v1.19.9 10.252.3.230 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
wrc6 Ready <none> 22h v1.19.9 10.252.3.232 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://19.3.9
访问 http://10.252.3.229:31940/k10/# in chrome web browser
7.结合 XSKY CSI 容器存储解决方案保护云原生应用测试
7.1 测试应用 mysql 的安装
$ kubectl create namespace mysql
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install mysql-release bitnami/mysql --namespace mysql \
--set auth.rootPassword='Start123' \
--set primary.persistence.size=10Gi
$ kubectl get pvc,po,svc -n mysql
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/data-mysql-release-0 Bound pvc-80ca8717-b99f-4197-ba88-97d5e0f8d5d8 10Gi RWO iscsi-sc 19h
NAME READY STATUS RESTARTS AGE
pod/mysql-release-0 1/1 Running 0 19h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mysql-release ClusterIP 10.97.128.29 <none> 3306/TCP 3m16s
service/mysql-release-headless ClusterIP None <none> 3306/TCP 3m16s
$ kubectl get statefulset -n mysql
NAME READY AGE
mysql-release 1/1 3m16s
7.2 应用程序发现
在应用程序安装完成之后,我们就可以在 Application 列表中发现这个应用了
7.3 应用程序的备份与恢复
7.3.1 建立 MySQL 数据集
# 登录到 MySQL Docker
$ kubectl exec -ti $(kubectl get pods -n mysql --selector=app.kubernetes.io/instance=mysql-release -o=jsonpath='{.items[0]
.metadata.name}') -n mysql -- bash
# 登录 MySQL
$ mysql --user=root --password=Start123
# 建立 "test" 数据库, 并使用这个库
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.04 sec)
mysql> USE test;
Database changed
# 创建 "pets" 表,
mysql> CREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
Query OK, 0 rows affected (0.29 sec)
# 插入一行数据
mysql> INSERT INTO pets VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
Query OK, 1 row affected (0.05 sec)
# 查看 "pets" 表中的数据
mysql> SELECT * FROM pets;
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+-------+---------+------+------------+-------+
1 row in set (0.00 sec)
7.3.2 创建 Policy 保护 MySQL 应用
创建 Policy 保护 MySQL 应用,之后点击 Run Once
查看 Dashboard 中的快照备份已经完成,并生成了还原点。
查看系统中快照已经生成
$ kubectl get pvc -n mysql
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-mysql-release-0 Bound pvc-80ca8717-b99f-4197-ba88-97d5e0f8d5d8 10Gi RWO iscsi-sc 20h
$ kubectl get volumesnapshot -n mysql
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
k10-csi-snap-m75ctlppjx7jjksx true data-mysql-release-0 10Gi csi-snapclass snapcontent-54c5c5a8-82f6-404b-bfde-2fe88668b784 37m 38m
$ kubectl get volumesnapshotcontent -n mysql
NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT AGE
snapcontent-54c5c5a8-82f6-404b-bfde-2fe88668b784 true 10737418240 Delete iscsi.csi.xsky.com csi-snapclass k10-csi-snap-m75ctlppjx7jjksx 39m
$ kubectl get volumesnapshot -n mysql-restore1
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
k10-csi-snap-c6j28vzklskt59s8 true k10-csi-snap-c6j28vzklskt59s8-content-4f76d45b-bd62-4cea-9776-733666011859 0 k10-clone-csi-snapclass k10-csi-snap-c6j28vzklskt59s8-content-4f76d45b-bd62-4cea-9776-733666011859 35m 35m
7.3.3 模拟灾难 删除 MySQL 数据
# 登录 Mysql Pod 中的 MySQL 数据库
$ kubectl exec -ti $(kubectl get pods -n mysql --selector=app.kubernetes.io/instance=mysql-release -o=jsonpath='{.items[0]
.metadata.name}') -n mysql -- bash
$ mysql --user=root --password=Start123
# Drop the test database
$ mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> DROP DATABASE test;
Query OK, 1 row affected (0.03 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
7.3.4 还原 MySQL 数据
要恢复丢失的数据, 我们需要使用之前创建的备份时间点,进行 Policy 的 Restore 操作,在这里我们新建一个 namespace mysql-resore1。
在恢复的过程中我们可以观察 Dashboard 或从命令行查看新的 Namesspace 中 Pod 的部署情况, 这时查看系统可以发现 K10 利用快照 Clone 出的新的 PVC , DataSource 为 Snapshot , k10-csi-snap-c6j28vzklskt59s8
$kubectl get po -n mysql-restore1 -w
NAME READY STATUS RESTARTS AGE
mysql-release-0 1/2 Running 0 44s
mysql-release-0 1/2 Running 0 100s
mysql-release-0 2/2 Running 0 110s
# 查看系统,发现 K10 利用快照 Clone 出的新的 PVC , DataSource 为 Snapshot , k10-csi-snap-c6j28vzklskt59s8
$ kubectl get volumesnapshotcontent -n mysql-restore1
NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT AGE
k10-csi-snap-c6j28vzklskt59s8-content-4f76d45b-bd62-4cea-9776-733666011859 true 0 Retain iscsi.csi.xsky.com k10-clone-csi-snapclass k10-csi-snap-c6j28vzklskt59s8 35m
$ kubectl get pvc -n mysql-restore1
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-mysql-release-0 Bound pvc-58e94745-5909-4527-b4ed-3507d2bbdae0 10Gi RWO iscsi-sc 39m
$ kubectl describe pvc -n mysql-restore1
Name: data-mysql-release-0
Namespace: mysql-restore1
StorageClass: iscsi-sc
Status: Bound
Volume: pvc-58e94745-5909-4527-b4ed-3507d2bbdae0
Labels: app.kubernetes.io/component=primary
app.kubernetes.io/instance=mysql-release
app.kubernetes.io/name=mysql
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: iscsi.csi.xsky.com
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 10Gi
Access Modes: RWO
VolumeMode: Filesystem
DataSource:
APIGroup: snapshot.storage.k8s.io
Kind: VolumeSnapshot
Name: k10-csi-snap-c6j28vzklskt59s8 #
Mounted By: mysql-release-0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Provisioning 39m iscsi.csi.xsky.com_csi-sidecar-iscsi-provisioner-86d4c4df75-zwzl8_c75cf560-e7e8-44fb-a743-0e766d6c4ab8 External provisioner is provisioning volume for claim "mysql-restore1/data-mysql-release-0"
Normal ExternalProvisioning 39m (x3 over 39m) persistentvolume-controller waiting for a volume to be created, either by external provisioner "iscsi.csi.xsky.com" or manually created by system administrator
Normal ProvisioningSucceeded 39m iscsi.csi.xsky.com_csi-sidecar-iscsi-provisioner-86d4c4df75-zwzl8_c75cf560-e7e8-44fb-a743-0e766d6c4ab8 Successfully provisioned volume pvc-58e94745-5909-4527-b4ed-3507d2bbdae0
$ kubectl describe pvc -n mysql-restore1
7.3.5 查看还原后的 MySQL 数据
查看已经删除的数据表,可以看到数据已经恢复了
# 登录 Mysql Pod 中的 MySQL 数据库
$ kubectl exec -ti $(kubectl get pods -n mysql-restore1 --selector=app.kubernetes.io/instance=mysql-release -o=jsonpath='{.items[0].metadata.name}') -n mysql-restore1 -- bash
$ mysql --user=root --password=Start123
# 查看已经删除的数据表,可以看到数据已经恢复了
$ mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| my_database |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
6 rows in set (0.01 sec)
$ mysql> USE test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
$ mysql> SELECT * FROM pets;
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+-------+---------+------+------------+-------+
1 row in set (0.03 sec)
8. 将数据 Export 到 XSKY 的对象存储实现数据的长期保留
8.1 创建 Location Profile
8.2 编辑 Policy 设定将快照备份导出到 xsky 对象存储
8.3 点击 Run Once 运行新规则
8.4 查看 数据备份进行程
如下图,我们可以看到数据已经 Export 到 S3 Bucket ,并切意识到这个一个数据库自动启动Kanister 应用感知的备份。
从 xsky 的 S3 存储桶上可以浏览到,数据已经存在
8.5 利用对象存储库的备份集进行恢复
查看还原的进程,
8.6 从 k8s 上确认数据已经恢复
$ kubectl get po -n mysql-restore-from-s3-bucket
NAME READY STATUS RESTARTS AGE
mysql-release-0 2/2 Running 0 3m33s
8.7 从 Kasten K10 上观察存储库的数据使用情况。
8.8 利用存储桶复制的方法避免人为错误
在日常运维过程中,有时会因为人为的原因导致本地的存储桶数据丢失。这时我们可以使用 Xsky 对象存储的桶复制功能,直接将存储桶的数据复制到远端,在设置桶复制规则时,可以设置为禁用删除操作,这样我们就可以避免人为或逻辑错误,从远端的存储桶恢复数据了。
恢复时,我们只要选择 Alternate Location Profile,并选择目标存储桶。本次的实验环境为,
源端: xsky-s3-bucket, 目标端:s3-bucket
9. 总结
我们验证了结合 XSKY CSI 容器存储解决方案保护云原生应用的方法。首先,我们利用 Kubestr 对云原生存储进行评测,并使用 K10 对存储 CSI 进行调用生成快照,达成最快速的 RPO 与 RTO的备份与恢复,最后,我们利用 Xsky的对象存储,将快照数据导出到对象存储桶上,实现了异地容灾与数据长期保留,欢迎与我们讨论您的观点与想法!
10.参考链接
- Kubernetes Container Storage Interface (CSI) Documentation
https://kubernetes-csi.github.io/docs/)- Kasten k10 实战系列 03 CSI 存储快照适配
https://www.data2clouds.com/?p=69- Kasten k10 实战系列 04 - 利用 Kubestr 进行云原生存储能力评测
https://www.data2clouds.com/?p=71/- Kasten K10 系统需求
https://docs.kasten.io/latest/operating/footprint.html- 详解支持 kubernetes CSI的持久化容器存储
https://www.xsky.com/tec/5609/- 同时支持iSCSI和NFS,XSKY SDS V5的K8s CSI卷扩展功能是如何炼成的
https://zhuanlan.zhihu.com/p/413226030- XSKY 星辰天合云原生容器存储解决方案
https://www.xsky.com/solution-cloud-native/- Complete List of K10 Helm Options
https://docs.kasten.io/latest/install/advanced.html
10.欢迎关注
欢迎关注 www.data2clouds.com Mars Zhang @ 云端数据管理