Contents

kube-backup: 基于ArgoWorkflow与Restic的k8s简单备份方案

前言

又双叒叕好久没写了哈哈哈哈。

生活有了变化,时间开始不太够花了。但是话又说回来,一些习惯或者兴趣确实是时间充裕,人开始无聊的时候才会想要去做,以前会觉得这些兴趣爱好就不是自己真心喜欢的。但是现在想来,或许不应该把想做的事情太认真对待,管它喜不喜欢呢,我当下是想做的,就花心思认真做好,就够了。

当然,确实也希望自己能有一份长久的热爱,能够跨越时间,去充当生活的一个支点。

kube-backup

今天简单介绍一下自己最近在写的一个小项目好了。我把它叫做kube-backup,是一个简单的k8s pvc备份工具。

随着公司内越来越多应用搬迁到k8s上运行,应用团队对pvc备份的需求越发明显。于是我便花了点时间开发了一个相对通用的备份方案,用于对运行在k8s上的应用所使用的pvc进行备份和故障恢复。它的核心能力是,使用argo workflow来编排系统涉及到的pod的暂停,然后将指定的多数个pvc,通过restic,备份到统一的一块备份用的pvc中,然后将所有pod启动回来,恢复的时候同理。

下面是github链接:

GitHub - midknight24/kube-backup

安装

  1. 安装argo workflow到集群中,请参考官方的安装指南

  2. 按照需求修改data.yaml文件,然后使用ytt,把workflow yaml都渲染出来

    1
    
    ytt -f templates/ --data-values-file data.yaml  --output-files ./output
    
  3. 安装rbac资源,用于argo workflow在系统所在的namespace进行备份操作

    1
    
    kubectl create -f ./output/rbac
    
  4. 把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-pvcautoquiz-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-pvcautoquiz-test-pvcautoquiz-backup-pvc 其中前两个是要备份的pvc,而后者则是存放备份数据的pvc。除了pvc之外,workflow的另一个核心便是定义具体执行的steps。对于每个step, argo workflow会在指定的namespace下生成对应的pod来运行。可以看见,我们一个有四个steps: pause-resourcesbackup-autoquiz-mysql-pvcbackup-autoquiz-test-pvcresume-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比起来要简陋一些😂