前言
又双叒叕好久没写了哈哈哈哈。
生活有了变化,时间开始不太够花了。但是话又说回来,一些习惯或者兴趣确实是时间充裕,人开始无聊的时候才会想要去做,以前会觉得这些兴趣爱好就不是自己真心喜欢的。但是现在想来,或许不应该把想做的事情太认真对待,管它喜不喜欢呢,我当下是想做的,就花心思认真做好,就够了。
当然,确实也希望自己能有一份长久的热爱,能够跨越时间,去充当生活的一个支点。
kube-backup
今天简单介绍一下自己最近在写的一个小项目好了。我把它叫做kube-backup,是一个简单的k8s pvc备份工具。
随着公司内越来越多应用搬迁到k8s上运行,应用团队对pvc备份的需求越发明显。于是我便花了点时间开发了一个相对通用的备份方案,用于对运行在k8s上的应用所使用的pvc进行备份和故障恢复。它的核心能力是,使用argo workflow来编排系统涉及到的pod的暂停,然后将指定的多数个pvc,通过restic,备份到统一的一块备份用的pvc中,然后将所有pod启动回来,恢复的时候同理。
下面是github链接:
GitHub - midknight24/kube-backup
安装
-
安装argo workflow到集群中,请参考官方的安装指南
-
按照需求修改data.yaml
文件,然后使用ytt,把workflow yaml都渲染出来
1
|
ytt -f templates/ --data-values-file data.yaml --output-files ./output
|
-
安装rbac资源,用于argo workflow在系统所在的namespace进行备份操作
1
|
kubectl create -f ./output/rbac
|
-
把workflow template安装到集群中
1
|
kubectl create -f ./output/workflow-template
|
data.yaml的例子如下,参数都挺自说明的:
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
|
# 应用名
appName: autoquiz
# 应用所在命名空间
namespace: autoquiz
# 备份仓库 PVC 名称,需要是ReadWriteMany的
repoPvc:
name: autoquiz-backup-pvc
# 需要暂停和恢复的工作负载
workloads:
- name: deployment/autoquiz-pub
replica: 3
timeout: 120s
- name: deployment/autoquiz-quiz
replica: 3
- name: deployment/autoquiz-user
replica: 1
- name: statefulset/autoquiz-mysql
replica: 1
# 需要备份的 PVC 列表
backupPvcs:
- name: autoquiz-mysql-pvc
- name: autoquiz-test-pvc
|
使用的说明请参考github里面吧~
备份与恢复原理
下面重点介绍一下这个工具背后的原理。我们直接从渲染出来的yaml文件夹作为切入点:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
output
├── rbac
│ ├── rb.yml
│ ├── role.yml
│ └── sa.yml
├── workflow
│ ├── manage-backup.yml
│ ├── manage-restore.yml
│ └── show-snapshots.yml
└── workflow-template
├── backup-workflow-tmpl.yml
├── pause-workflow-tmpl.yml
├── restore-workflow-tmpl.yml
├── resume-workflow-tmpl.yml
└── show-snapshots-workflow-template.yml
|
rbac文件夹就不多赘述了,重点看workflow和workflow-template文件夹。workflow-template存放的是所有用备份的系统相关的工作流模板,其本质是argo workflow的WorkflowTemplate
CRD,用户可以传入参数调整具体行为,而在kube-backup中,则会由workflow文件夹中的Workflow
来进行距具体的传参和调用。
接下来,我们来具体看看备份的workflow yaml,假设我们的应用叫autoquiz,然后备份的时候,需要对autoquiz-mysql-pvc
和autoquiz-test-pvc
两个pvc进行备份,那yaml如下所示:
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
|
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: autoquiz-manage-backup-workflow-
namespace: autoquiz
spec:
serviceAccountName: backup-sa
entrypoint: backup
volumes:
- name: backup-repo
persistentVolumeClaim:
claimName: autoquiz-backup-pvc
- name: autoquiz-mysql-pvc-source
persistentVolumeClaim:
claimName: autoquiz-mysql-pvc
- name: autoquiz-test-pvc-source
persistentVolumeClaim:
claimName: autoquiz-test-pvc
templates:
- name: backup
steps:
- - name: pause-resources
templateRef:
name: pause-workflow-template
template: pause-resources
arguments:
parameters:
- name: resources
value: '[{"name":"deployment/autoquiz-pub","timeout":"120s"},{"name":"deployment/autoquiz-quiz","timeout":"60s"},{"name":"deployment/autoquiz-user","timeout":"60s"},{"name":"statefulset/autoquiz-mysql","timeout":"60s"}]'
- - name: backup-autoquiz-mysql-pvc
templateRef:
name: backup-autoquiz-mysql-pvc-workflow-template
template: backup-resource
arguments:
parameters:
- name: backup-id
value: '{{workflow.creationTimestamp}}'
- name: backup-autoquiz-test-pvc
templateRef:
name: backup-autoquiz-test-pvc-workflow-template
template: backup-resource
arguments:
parameters:
- name: backup-id
value: '{{workflow.creationTimestamp}}'
- - name: resume-resources
templateRef:
name: resume-workflow-template
template: resume-resources
arguments:
parameters:
- name: resources
value: '[{"name":"deployment/autoquiz-pub","replica":3},{"name":"deployment/autoquiz-quiz","replica":3},{"name":"deployment/autoquiz-user","replica":1},{"name":"statefulset/autoquiz-mysql","replica":1}]'
|
可以看见,在上面yaml中,我们声明了要使用的pvc:autoquiz-mysql-pvc
、 autoquiz-test-pvc
和autoquiz-backup-pvc
其中前两个是要备份的pvc,而后者则是存放备份数据的pvc。除了pvc之外,workflow的另一个核心便是定义具体执行的steps。对于每个step, argo workflow会在指定的namespace下生成对应的pod来运行。可以看见,我们一个有四个steps: pause-resources
、backup-autoquiz-mysql-pvc
、backup-autoquiz-test-pvc
和resume-resources
,其中,中间两个steps是并行运行的。它们都使用了templateRef来引用workflow-template文件夹中的workflow template来执行具体的逻辑,workflow负责整体的编排和传参。
比如说,我们看看backup-autoquiz-mysql-pvc-workflow-template
:
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
|
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: backup-autoquiz-mysql-pvc-workflow-template
namespace: autoquiz
spec:
entrypoint: backup-resource
templates:
- name: backup-resource
inputs:
parameters:
- name: backup-id
script:
image: midknight24/restic
command:
- bash
volumeMounts:
- name: backup-repo
mountPath: /autoquiz-mysql-pvc/backup
subPath: autoquiz-mysql-pvc
- name: autoquiz-mysql-pvc-source
mountPath: /source/autoquiz-mysql-pvc
source: |
#!/bin/sh
set -e
export RESTIC_REPOSITORY=/autoquiz-mysql-pvc/backup
export RESTIC_PASSWORD=abcd1234
restic init || true
restic backup --host autoquiz-mysql-pvc --tag {{inputs.parameters.backup-id}} /source/autoquiz-mysql-pvc
restic snapshots
restic forget --keep-last 3 --prune
|
可以看见,这里便是具体使用restic来进行备份的地方——backup workflow传入参数(backup-id)和pvc,workflow template将他们挂载到具体的pod路径中,并执行restic backup。值得注意的是,我们会使用backup-id来给备份打一个tag,而这个backup-id则取自workflow生成的时间值,通过这个逻辑,我们使每次备份中所有的restic backup都有同一个tag,这样,后续要恢复的时候,便能使所有pvc都统一恢复到想要备份的版本。
效果图
下面是argo workflow中一次backup-workflow的画面:
有一说一,argo workflow的界面比argoCD比起来要简陋一些😂