[TOC]

0x00 前言简述

引言

在运维安全管理中容灾备份是非常重要的一环, 那在Kubernetes集群中如何进行备份和迁移 Kubernetes 资源和持久卷数据。
常常采用手动进行容灾备份, 如备份资源清单、或者helm模板,但是针对Kubernetes 资源和持久卷(PV/PVC)中得数据无法进行备份迁移,所以在这样得场景下我们就需要 Velero 是一个开源工具。


1.Velero 基础概述

What: 什么是 Velero?

答: Velero (以前称为 Heptio Ark)是一个开源工具,用于安全备份和恢复、执行灾难恢复以及迁移 Kubernetes 集群资源和持久卷。


Why: 为啥要使用 Velero?

答: Velero 可以让您备份您的集群并在丢失时恢复将集群资源迁移到其他集群将您的生产集群复制到开发和测试集群, 详细解析说明:

  • 1.灾难恢复 : 在基础设施丢失、数据损坏和/或服务中断的情况下减少恢复时间。
  • 2.数据迁移 : 通过轻松地将 Kubernetes 资源从一个集群迁移到另一个集群,实现集群可移植性。
  • 3.数据保护 : 提供关键数据保护功能,例如计划备份、保留计划以及用于自定义操作的备份前或备份后挂钩。

Velero 特点: 您可以备份或恢复集群中的所有对象,也可以按类型、命名空间和/或标签过滤对象。

  • 1.备份集群 : 使用命名空间或标签选择器为整个集群或集群的一部分备​​份 Kubernetes 资源和卷。
  • 2.计划备份 : 设置计划以定期自动启动备份。
  • 3.备份挂钩 : 配置备份前和备份后挂钩,以在 Velero 备份之前和之后执行自定义操作。


How: 你如何使用 Velero?

答: 您可以通过云提供商或本地运行 Velero, 其组件包括在集群上运行的服务器本地运行的命令行客户端
使用Minio服务进行管理存储备份在ETCD的数据、使用velero客户端进行备份和还原操作。


2.Velero 工作原理

描述: 一般得使用Velero主要是从以下三个方面入手。

  • 1.按需备份: 将复制的 Kubernetes 对象的 tarball 上传到云对象存储中,调用云提供商 API 以制作持久卷的磁盘快照(如果指定)。
  • 2.计划备份: 由 Cron 表达式指定在循环间隔备份您的数据,计划备份以名称保存<SCHEDULE NAME>-<TIMESTAMP>,其中<TIMESTAMP>格式为YYYYMMDDhhmmss
  • 3.容灾恢复: 该恢复操作可以恢复所有对象和持久卷从先前创建的备份,还原的默认名称为<BACKUP NAME>-<TIMESTAMP>, 恢复的对象还包括一个带有 key velero.io/restore-name 和 value的标签<RESTORE NAME>
  • 4.备份过期: 可以通过添加标志来指定--ttl <DURATION>参数来设置备份得生存时间(默认30天)。到期后则会删除备份资源、来自云对象存储的备份文件、所有 PersistentVolume 快照、所有关联的恢复
  • 5.对象存储同步: 它会不断检查以确保始终存在正确的备份资源。如果存储桶中有格式正确的备份文件,但 Kubernetes API 中没有相应的备份资源,Velero 会将信息从对象存储同步到 Kubernetes。


备份工作流程:
描述: 当你运行velero backup create test-backup命令。

1.Velero 客户端调用 Kubernetes API 服务器来创建一个Backup对象。

2.该 BackupController 注意到新的 Backup 对象并进行验证。

3.在 BackupController 开始备份过程。它通过向 API 服务器查询资源来收集要备份的数据。

4.将 BackupController 使得对象存储服务的调用-例如,AWS S3 -上传备份文件。

默认情况下 velero backup create 为任何持久卷制作磁盘快照, 可以通过指定附加标志来调整快照--snapshot-volumes=false(使用选项禁用快照)。

WeiyiGeek.backup-process

WeiyiGeek.backup-process

Tips : 实际上 VeleroKubernetes 集群中创建了很多 CRD 以及相关的控制器,进行备份恢复等操作实质上是对相关 CRD 的操作。

Tips : Velero 使用 Kubernetes API 服务器的首选版本为每个组/资源备份资源。恢复资源时,目标集群中必须存在相同的 API 组/版本才能成功恢复。


3.Provider 插件供应商

描述: Velero 有一个插件系统支持各种存储提供程序,用于不同的备份和快照操作。它允许任何人在不修改 Velero 代码库的情况下为其他备份和卷存储平台添加兼容性。

Velero 支持的备份存储Provider

提供者 对象存储 卷快照程序 插件提供程序存储库 安装说明
亚马逊网络服务 (AWS) AWS S3 AWS EBS 适用于 AWS 的 Velero 插件 AWS 插件设置 (以及s3兼容的存储比如minio)
谷歌云平台 (GCP) 谷歌云存储 谷歌计算引擎磁盘 GCP 的 Velero 插件 GCP 插件设置
微软 Azure Azure Blob 存储 Azure 托管磁盘 适用于 Microsoft Azure 的 Velero 插件 Azure 插件设置
VMware vSphere 🚫 vSphere 卷 VMware vSphere vSphere 插件设置
容器存储接口 (CSI) 🚫 CSI 卷 CSI 的 Velero 插件 CSI 插件设置


Velero 社区支持的Provider

Provider Object Store Volume Snapshotter Plugin Documentation Contact
AlibabaCloud Alibaba Cloud OSS Alibaba Cloud AlibabaCloud GitHub Issue
DigitalOcean DigitalOcean Object Storage DigitalOcean Volumes Block Storage StackPointCloud
Hewlett Packard 🚫 HPE Storage Hewlett Packard Slack, GitHub Issue
OpenEBS 🚫 OpenEBS CStor Volume OpenEBS Slack, GitHub Issue
OpenStack Swift Cinder OpenStack GitHub Issue
Portworx 🚫 Portworx Volume Portworx Slack, GitHub Issue
Storj Storj Object Storage 🚫 Storj GitHub Issue


4.补充说明

参考来源:


0x01 环境部署

1.先决条件

  • Kubernetes 集群 API Version >= 1.7
  • Kubernetes 集群已部署 DNS 服务器 (例如: CoreDNS)。
  • 在 Minio 中存储备份可用磁盘空间少于 1GB,Minio 将无法运行。


2.下载部署 Velero

  • 1.下载 最新的官方版本的tarball,每个版本的 tarball 都包含velero命令行客户端,,并将elero二进制文件从 Velero 目录移动到 PATH 中的某个位置。
1
2
3
curl -fSL https://github.com/vmware-tanzu/velero/releases/download/v1.6.2/velero-v1.6.2-linux-amd64.tar.gz 
tar -zxvf velero-v1.6.2-linux-amd64.tar.gz -C /usr/local/
ln -s /usr/local/velero-v1.6.2-linux-amd64/velero /usr/bin/velero
  • 2.验证 Velero Client
    1
    2
    3
    4
    velero version
    Client:
    Version: v1.6.2
    Git commit: 8c9cdb9603446760452979dc77f93b17054ea1cc

3.设置Minio服务器

描述: 这些指令启动 Velero 服务器和一个只能从集群内部访问的 Minio 实例,我们可以配置集群以从外部访问 Minio 的信息,访问日志和运行velero describe命令需要外部访问。

  • 1.在本地目录中创建 Velero 特定的凭据文件。
1
2
3
4
5
tee /tmp/credentials-velero <<'EOF'
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF


  • 2.修改启动服务器和本地存储服务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# 在 Velero 目录中解压目录中 修改 examples/minio/00-minio-deployment.yaml , 内容如下
---
apiVersion: v1
kind: Namespace
metadata:
name: velero

---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
strategy:
type: Recreate
selector:
matchLabels:
component: minio
template:
metadata:
labels:
component: minio
spec:
volumes:
- name: storage
emptyDir: {}
- name: config
emptyDir: {}
containers:
- name: minio
image: minio/minio:latest
imagePullPolicy: IfNotPresent
# 设置静态得Console监控端口(推荐)
args:
- server
- /storage
- --config-dir=/config
- --console-address
- ":31234"
# 注意事项: 主要修改点是以下环境变量名称`MINIO_ROOT_USER|MINIO_ROOT_PASSWORD`否则。
# WARNING: MINIO_ACCESS_KEY and MINIO_SECRET_KEY are deprecated.
# Please use MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
env:
- name: MINIO_ROOT_USER
value: "minio"
- name: MINIO_ROOT_PASSWORD
value: "minio123"
# Pod 暴露 minio 服务和 console web 服务端口以供SVC使用
ports:
- name: web
containerPort: 9000
- name: console
containerPort: 31234
volumeMounts:
- name: storage
mountPath: "/storage"
- name: config
mountPath: "/config"
---
apiVersion: v1
kind: Service
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
# ClusterIP is recommended for production environments.
# Change to NodePort if needed per documentation,
# but only if you run Minio in a test/trial environment, for example with Minikube.
type: NodePort
ports:
- name: web
port: 9000
targetPort: 9000
nodePort: 30090
protocol: TCP
- name: console
port: 31234
targetPort: 31234
nodePort: 31234
protocol: TCP
selector:
component: minio

---
apiVersion: batch/v1
kind: Job
metadata:
namespace: velero
name: minio-setup
labels:
component: minio
spec:
template:
metadata:
name: minio-setup
spec:
restartPolicy: OnFailure
volumes:
- name: config
emptyDir: {}
containers:
- name: mc
image: minio/mc:latest
imagePullPolicy: IfNotPresent
# Minio状态检测
command:
- /bin/sh
- -c
- "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero"
volumeMounts:
- name: config
mountPath: "/config"

Tips: 注意 Velero 1.6.2 版本中minio得yaml配置文件我们需要相应进行改变。

Tips: 注意 提供的 Minio yaml 示例使用”空目录”,您的节点需要有足够的可用空间来存储要备份的数据以及 1GB 的可用空间。如果节点没有足够的空间,您可以修改示例 yaml 以使用 Persistent Volume 而不是empty dir

Tips : 注意 使用 Service 在集群外公开 Minio 时需要Pod暴露两个应用端口即Service 9000Console 默认随机,此时你可以将将 Minio 服务类型从更改ClusterIP为NodePort,具体配置查看上述资源清单。


  • 2.部署minio资源清单以及服务查看
1
2
3
4
5
6
7
8
9
10
# 使用本地集群minio作为备份存储
kubectl apply -f examples/minio/00-minio-deployment.yaml
# namespace/velero created
# deployment.apps/minio created
# service/minio created
# job.batch/minio-setup created

kubectl get svc -n velero
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/minio NodePort 10.100.123.198 <none> 9000:30090/TCP,31234:31234/TCP 7m25s

此时访问http://192.168.12.107:30090 可以看到 Minio 服务端, 此时它会访问跳转 http://192.168.12.107:31234/login, 登录得账号密码: minio / minio123

WeiyiGeek.minio资源服务查看

WeiyiGeek.minio资源服务查看


  • 3.在客户端中安装 velero 客户端。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 获取指定 minio 服务地址和服务端口
minio_service_ip="192.168.12.107"
minio_service_port=$(kubectl -n velero get svc/minio -o jsonpath='{.spec.ports[0].nodePort}')

# kubernetes Master 节点上安装 velero 或者在其他集群上安装执行
velero install \
--image velero/velero:v1.6.2 \
--provider aws \
--bucket velero \
--namespace velero \
--plugins velero/velero-plugin-for-aws:v1.2.0 \
--secret-file /tmp/credentials-velero \
--velero-pod-cpu-request 200m \
--velero-pod-mem-request 200Mi \
--velero-pod-cpu-limit 1000m \
--velero-pod-mem-limit 1000Mi \
--use-volume-snapshots=false \
--use-restic \
--restic-pod-cpu-request 200m \
--restic-pod-mem-request 200Mi \
--restic-pod-cpu-limit 1000m \
--restic-pod-mem-limit 1000Mi \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://${minio_service_ip}:${minio_service_port}

# 出现下述表示安装成功, 并且此时可以看到相关服务已经正常运行,Job 任务正常完成退出,大量 CRD 被创建。
# Velero is installed! ⛵ Use 'kubectl logs deployment/velero -n velero' to view the status.


  • 4.在kubernetes主节点中验证查看velero部署得所有服务。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    $ kubectl get all -n velero
    # NAME READY STATUS RESTARTS AGE
    # pod/minio-b46c8d7d5-4qt4x 1/1 Running 0 4m50s
    # pod/restic-568nx 1/1 Running 0 98s
    # .......
    # pod/restic-vs5s9 1/1 Running 0 98s
    # pod/velero-7b8b8fc8f-rcwb2 1/1 Running 0 98s

    # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    # service/minio NodePort 10.100.123.198 <none> 9000:30090/TCP,31234:31234/TCP 9m10s

    # NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
    # daemonset.apps/restic 4 4 4 4 4 <none> 98s

    # NAME READY UP-TO-DATE AVAILABLE AGE
    # deployment.apps/minio 1/1 1 1 10m
    # deployment.apps/velero 1/1 1 1 98s

    # NAME DESIRED CURRENT READY AGE
    # replicaset.apps/minio-57c7d49f8c 0 0 0 6m
    # replicaset.apps/minio-6489c45fb5 0 0 0 10m
    # replicaset.apps/minio-b46c8d7d5 1 1 1 4m50s
    # replicaset.apps/velero-7b8b8fc8f 1 1 1 98s

    # NAME COMPLETIONS DURATION AGE
    # job.batch/minio-setup 0/1 9m10s 9m10s

    $ kubectl logs -n velero pod/minio-b46c8d7d5-4qt4x
    # API: http://172.16.100.91:9000 http://127.0.0.1:9000
    # Console: http://172.16.100.91:31234 http://127.0.0.1:31234
    # Documentation: https://docs.min.io


  • 5.至此安装velero服务已经成功。
    1
    2
    3
    4
    5
    6
    $ velero version
    Client:
    Version: v1.6.2
    Git commit: 8c9cdb9603446760452979dc77f93b17054ea1cc
    Server:
    Version: v1.6.2

0x02 备份迁移实践

1.官方示例

  • Step 1.部署在velero解压目录中得examples/nginx-app/base.yaml文件, 部署示例 nginx 应用程序。
1
2
3
4
$ kubectl apply -f examples/nginx-app/base.yaml
# namespace/nginx-example created
# deployment.apps/nginx-deployment created
# service/my-nginx created


  • Step 2.检查是否成功创建了部署 Velero 给出的 nginx-app 示例 。
1
2
kubectl get deployments -l component=velero --namespace=velero
kubectl get deployments --namespace=nginx-example
  • Step 3.为与app=nginx标签选择器匹配的任何对象创建备份。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    $ velero backup create nginx-backup --selector app=nginx

    $ velero backup describe nginx-backup --details
    # Name: nginx-backup
    # Namespace: velero
    # Labels: velero.io/storage-location=default
    # Annotations: velero.io/source-cluster-k8s-gitversion=v1.19.6
    # velero.io/source-cluster-k8s-major-version=1
    # velero.io/source-cluster-k8s-minor-version=19
    # .......
    # Phase: Completed

    # Resource List:
    # apps/v1/ReplicaSet:
    # - nginx-example/nginx-deployment-57d5dcb68
    # v1/Endpoints:
    # - nginx-example/my-nginx
    # v1/Namespace:
    # - nginx-example
    # v1/Pod:
    # - nginx-example/nginx-deployment-57d5dcb68-78x8z
    # - nginx-example/nginx-deployment-57d5dcb68-hcptr
    # v1/Service:
    # - nginx-example/my-nginx

    # 或者如果要备份除与标签匹配的对象之外的所有对象 backup=ignore:
    $ velero backup create nginx-backup --selector 'backup notin (ignore)'
    # 使用app=nginx标签选择器根据 cron 表达式创建定期计划备份:
    $ velero schedule create nginx-daily --schedule="0 1 * * *" --selector app=nginx
    # 或者,您可以使用一些非标准速记 cron 表达式:
    $ velero schedule create nginx-daily --schedule="@daily" --selector app=nginx

    # 查看 velero 已备份的kubernetes应用数据
    $ velero backup get
    # NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
    # nginx-backup Completed 0 0 2021-08-06 19:04:21 +0800 CST 29d default app=nginx


  • Step 4.容灾恢复实战流程示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1.模拟灾难删除名称空间将会删除其下控制器。
kubectl delete namespace nginx-example

# 2.要检查 nginx 部署和服务是否消失请运行。
kubectl get deployments --namespace=nginx-example
kubectl get services --namespace=nginx-example
kubectl get namespace/nginx-example
# Tips : 注意您可能需要等待几分钟才能完全清理命名空间。

# 3.利用 velero 中得备份进行恢复刚才删除名称空间以及下面得各种控制器
velero restore create --from-backup nginx-backup
# Restore request "nginx-backup-20210806191516" submitted successfully.
# Run `velero restore describe nginx-backup-20210806191516` or `velero restore logs nginx-backup-20210806191516` for more details.

# 4.备份还原 nginx-backup 状态查看, 成功恢复后该STATUS列Completed, 并WARNINGS和ERRORS为0的所有对象nginx-example的命名空间应该只是因为他们是你删除了他们面前。
velero restore get
# NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
# nginx-backup-20210806191516 nginx-backup Completed 2021-08-06 19:15:16 +0800 CST 2021-08-06 19:15:16 +0800 CST 0 0 2021-08-06 19:15:16 +0800 CST <none>

# 5.如果有错误或警告可以详细查看,例如上述的 nginx-backup-20210806191516 还原记录。
velero restore describe nginx-backup-20210806191516

# 6.查看还原的Nginx服务是否已经正常。
kubectl get pod -l app=nginx


  • Step 5.删除您创建的任何备份,包括对象存储和持久卷快照中的数据你可以进行如下操作。
1
2
3
4
5
6
7
8
9
10
11
# - 1.删除指定名称的备份
$ velero backup delete nginx-backup

# - 2.删除所有备份
$ velero backup delete --all
# Are you sure you want to continue (Y/N)? y
# Request to delete backup "nginx-backup" submitted successfully.
# The backup will be fully deleted after all associated data (disk snapshots, backup files, restores) are removed.

# - 3.完全删除后,运行时备份将不再可见:
velero backup get nginx-backup


  • Step 6.要从 Kubernetes 集群中完全卸载 Velero、minio 和 nginx 示例应用程序:
    1
    2
    3
    kubectl delete namespace/velero clusterrolebinding/velero
    kubectl delete crds -l component=velero
    kubectl delete -f examples/nginx-app/base.yaml


Tips : 在 Docker (KinD) 中使用 Kubernetes 在集群外公开 Minio

1
2
3
4
5
6
# 1.您可以使用端口转发来访问 Minio 存储桶。
MINIO_POD=$(kubectl get pods -n velero -l component=minio -o jsonpath='{.items[0].metadata.name}')
kubectl port-forward $MINIO_POD -n velero 9000:9000

# 2.然后在另一个终端中执行如下命令, 并且将`publicUrl: http://localhost:9000`在该spec.config部分下添加。
kubectl edit backupstoragelocation default -n velero


2.实战容灾恢复

环境说明:

1
2
3
4
5
6
- 自定义镜像: harbor.weiyigeek.top/devops/tomee:8.0.6-webprofile
- 应用war包: HelloWorld-v1.43.war
- 部署资源清单: HelloWorld.yaml

$ ls
HelloWorld-v1.43.war HelloWorld.yaml


  • Step 1.部署资源清单一览(该应用演示包含动态持久化的PVC/PV卷 )
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    apiVersion: v1
    kind: Service
    metadata:
    name: deploy-maven-svc
    labels:
    app: java-maven
    spec:
    type: NodePort # Service 类型
    selector:
    app: java-maven # 【注意】与deployment资源控制器创建的Pod标签进行绑定;
    release: stabel # Service 服务发现不能缺少Pod标签,有了Pod标签才能与之SVC对应
    ports: # 映射端口
    - name: http
    port: 8080 # cluster 访问端口
    targetPort: 8080 # Pod 容器内的服务端口
    nodePort: 30089
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
    name: deploy-java-maven
    labels:
    app: java-maven
    spec:
    serviceName: "deploy-maven-svc"
    replicas: 3 # 副本数
    selector: # 选择器
    matchLabels:
    app: java-maven # 匹配的Pod标签非常重要
    release: stabel
    template:
    metadata:
    labels:
    app: java-maven # 模板标签
    release: stabel
    spec:
    volumes: # 关键点
    - name: webapps # 卷名称
    hostPath: # 采用hostPath卷
    type: DirectoryOrCreate # 卷类型DirectoryOrCreate: 如果子节点上没有该目录便会进行创建
    path: /nfsdisk-31/test/ # 各主机节点上已存在的目录此处是NFS共享
    - name: timezone # 容器时区设置
    hostPath:
    path: /usr/share/zoneinfo/Asia/Shanghai
    containers:
    - name: java-maven
    #image: harbor.weiyigeek.top/devops/tomcat:8.5.61-jdk8-corretto # 拉取的镜像
    image: harbor.weiyigeek.top/devops/tomee:8.0.6-webprofile
    imagePullPolicy: IfNotPresent
    command: ["bash","-c","rm -rf /usr/local/tomee/webapps/* && cp /tmp/${APPNAME} /usr/local/tomee/webapps/ROOT.war && catalina.sh run"]
    env:
    - name: APPNAME
    value: HelloWorld-v1.43.war
    ports:
    - name: http # 此端口在服务中的名称
    containerPort: 8080 # 容器暴露的端口
    volumeMounts: # 挂载指定卷目录
    - name: webapps # Tomcat 应用目录
    mountPath: /tmp/
    - name: logs # Tomcat 日志目录利用持久卷来进行存储。
    mountPath: /usr/local/tomee/logs
    - name: timezone # 镜像时区设置
    mountPath: /usr/share/zoneinfo/Asia/Shanghai
    volumeClaimTemplates: # 卷的体积要求模板此处采用StorageClass存储类主要针对于应用日志的存储;
    - metadata: # 根据模板自动创建PV与PVC并且进行一一对应绑定;
    name: logs
    spec:
    accessModes: [ "ReadWriteOnce" ]
    storageClassName: managed-nfs-storage # StorageClass存储类
    resources:
    requests:
    storage: 1Gi


  • Step 2.部署的java-maven应用信息查看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# (1) 查看 k8s 部署的 java-maven 应用
kubectl get pod,sts,svc -o wide -l app=java-maven
# NAME READY STATUS RESTARTS AGE
# pod/deploy-java-maven-0 1/1 Running 0 2d8h
# pod/deploy-java-maven-1 1/1 Running 0 2d8h
# pod/deploy-java-maven-2 1/1 Running 0 2d8h

# NAME READY AGE CONTAINERS IMAGES
# deploy-java-maven 3/3 2d9h java-maven harbor.weiyigeek.top/devops/tomee:8.0.6-webprofile

# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/deploy-maven-svc NodePort 10.106.80.8 <none> 8080:30089/TCP 2d9h

# (2) 验证查看部署的服务
$ curl 192.168.12.107:30089
# <p> Server : Apache Tomcat (TomEE)/9.0.41 (8.0.6) | 172.16.183.115 </p>
# <p> Client : 172.16.0.192 | 172.16.0.192</p>
# <p> Document_Root : /usr/local/tomee/webapps/ROOT/ <br/><br/> URL : 10.106.80.8/index.jsp </p>


  • Step 3.利用velero备份集群中 java-maven 应用。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    # (1) 指定备份带有 app=java-maven 标签的资源
    velero backup create java-maven --selector app=java-maven
    # Backup request "java-maven" submitted successfully.
    # Run `velero backup describe java-maven` or `velero backup logs java-maven` for more details.

    # (2) 查看备份的 java-maven 资源
    velero backup get
    # NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
    # java-maven Completed 0 0 2021-08-06 19:47:57 +0800 CST 29d default app=java-maven

    # (3) 备份的资源详细信息
    velero backup describe java-maven --details
    # Name: java-maven
    # Namespace: velero
    # Labels: velero.io/storage-location=default
    # Annotations: velero.io/source-cluster-k8s-gitversion=v1.19.6
    # velero.io/source-cluster-k8s-major-version=1
    # velero.io/source-cluster-k8s-minor-version=19

    # Phase: Completed
    # Errors: 0
    # Warnings: 0
    # Namespaces:
    # Included: *
    # Excluded: <none>
    # Resources:
    # Included: *
    # Excluded: <none>
    # Cluster-scoped: auto
    # Label selector: app=java-maven
    # Storage Location: default
    # Velero-Native Snapshot PVs: auto
    # TTL: 720h0m0s
    # Hooks: <none>
    # Backup Format Version: 1.1.0
    # Started: 2021-08-06 19:47:57 +0800 CST
    # Completed: 2021-08-06 19:47:59 +0800 CST
    # Expiration: 2021-09-05 19:47:57 +0800 CST
    # Total items to be backed up: 13
    # Items backed up: 13

    # Resource List:
    # apps/v1/ControllerRevision:
    # - default/deploy-java-maven-7664b769
    # apps/v1/StatefulSet:
    # - default/deploy-java-maven
    # v1/Endpoints:
    # - default/deploy-maven-svc
    # v1/PersistentVolume: # 可以看见备份的 PV 相关信息
    # - pvc-0a2c5013-db49-43f7-9e5f-5b29730b7938
    # - pvc-0c77d4da-f703-4a58-bee2-0ce25d3e8630
    # - pvc-563bcd3c-d994-4e46-8d4e-50694706366e
    # v1/PersistentVolumeClaim:
    # - default/logs-deploy-java-maven-0
    # - default/logs-deploy-java-maven-1
    # - default/logs-deploy-java-maven-2
    # v1/Pod:
    # - default/deploy-java-maven-0
    # - default/deploy-java-maven-1
    # - default/deploy-java-maven-2
    # v1/Service:
    # - default/deploy-maven-svc

    # Velero-Native Snapshots: <none included>
WeiyiGeek.在Minio查看java-maven备份情况

WeiyiGeek.在Minio查看java-maven备份情况

  • Step 4.此时我们模拟当不小心删除我们的Java-maven应用
    1
    2
    3
    4
    5
    6
    7
    8
    # 方式1
    kubectl delete sts deploy-java-maven
    statefulset.apps "deploy-java-maven" deleted

    # 方式2
    kubectl delete -f HelloWorld.yaml
    service "deploy-maven-svc" deleted
    statefulset.apps "deploy-java-maven" deleted


  • Step 5.利用velero来恢复我们的Java-maven应用

    1
    2
    3
    4
    5
    6
    velero restore create --from-backup java-maven
    # Restore request "java-maven-20210806204045" submitted successfully.
    # Run `velero restore describe java-maven-20210806204045` or `velero restore logs java-maven-20210806204045` for more details.

    velero restore get
    # java-maven-20210806204045 java-maven Completed 2021-08-06 20:40:45 +0800 CST 2021-08-06 20:40:46 +0800 CST 0 0 2021-08-06 20:40:45 +0800 CST <none>
  • Step 6.恢复后验证我们的Java-maven应用是否正常。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    kubectl get all -l app=java-maven
    # NAME READY STATUS RESTARTS AGE
    # pod/deploy-java-maven-0 1/1 Running 0 64s
    # pod/deploy-java-maven-1 1/1 Running 0 64s
    # pod/deploy-java-maven-2 1/1 Running 0 64s

    # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    # service/deploy-maven-svc NodePort 10.111.226.31 <none> 8080:30089/TCP 64s

    # NAME READY AGE
    # statefulset.apps/deploy-java-maven 3/3 64s

    # kubectl get pv,pvc -l app=java-maven
    # NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
    # persistentvolumeclaim/logs-deploy-java-maven-0 Bound pvc-0a2c5013-db49-43f7-9e5f-5b29730b7938 1Gi RWO managed-nfs-storage 73s
    # persistentvolumeclaim/logs-deploy-java-maven-1 Bound pvc-0c77d4da-f703-4a58-bee2-0ce25d3e8630 1Gi RWO managed-nfs-storage 73s
    # persistentvolumeclaim/logs-deploy-java-maven-2 Bound pvc-563bcd3c-d994-4e46-8d4e-50694706366e 1Gi RWO managed-nfs-storage 73s
WeiyiGeek.Java-maven应用状态

WeiyiGeek.Java-maven应用状态


0x0n 入坑出坑

1.采用Velero 1.6.2 提供得官方资源清单部署后从无法访问 MINIO Web-UI 管理界面

  • 问题信息:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ kubectl logs -n velero pod/minio-5b84955bdd-ptfs7
    WARNING: MINIO_ACCESS_KEY and MINIO_SECRET_KEY are deprecated.
    Please use MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
    API: http://192.168.109.99:9000 http://127.0.0.1:9000

    Console: http://192.168.109.99:35735 http://127.0.0.1:35735

    Documentation: https://docs.min.io

    WARNING: Console endpoint is listening on a dynamic port (35735), please use --console-address ":PORT" to choose a static port.
  • 问题原因:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 原因1.由上述得警告可知传递得minio账号密码得变量已变成如下,主要如不设置则默认credentials为'minioadmin:minioadmin'
    MINIO_ROOT_USER and MINIO_ROOT_PASSWORD

    docker run -p 30090:9000 \
    -e "MINIO_ROOT_USER=admin" \
    -e "MINIO_ROOT_PASSWORD=password" \
    minio/minio server /data

    # 原因2.Console 端口默认是动态随机端口需要采用如下参数进行指定。
    --console-address ":PORT"
  • 解决办法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    containers:
    - name: minio
    image: minio/minio:latest
    imagePullPolicy: IfNotPresent
    args:
    - server
    - /storage
    - --console-address
    - ":31234"
    - --config-dir=/config
    # 关键点1
    env:
    - name: MINIO_ROOT_USER
    value: "minio"
    - name: MINIO_ROOT_PASSWORD
    value: "minio123"
    # 关键点2
    ports:
    - name: web
    containerPort: 9000
    - name: console
    containerPort: 31234
    volumeMounts:
    - name: storage
    mountPath: "/storage"
    - name: config
    mountPath: "/config"