天天看點

備份恢複阿裡雲容器服務ACKVelero備份恢複阿裡雲容器服務ACK

Velero備份恢複阿裡雲容器服務ACK

1. 前言

不管是在傳統IT還是新興的雲計算場景下,對業務系統進行例行的備份都是一個非常重要的環節,本文将着重介紹如何使用開源工具

velero

給阿裡雲上的ACK k8s叢集進行例行備份,以及如何恢複,該方案可以作為ACK使用者日常運維的一個重要環節。

velero可以幫助我們:

  • 災備場景,提供備份恢複k8s叢集的能力
  • 遷移場景,提供拷貝叢集資源到其他叢集的能力(複制同步開發,測試,生産環境的叢集配置,簡化環境配置)

2. 環境準備

  1. 部署ACK kubernetes叢集 ,我們首先在阿裡雲張家口region建立了一個k8s叢集
  2. 建立OSS Bucket ,在張家口region建立一個OSS bucket用于velero備份
  3. 下載下傳安裝官方velero用戶端( https://github.com/heptio/velero
  4. 安裝velero ACK plugin( https://github.com/AliyunContainerService/velero-plugin

velero包含有一個用戶端一個服務端,服務端以velero ACK plugin方式部署在k8s叢集中(詳見github說明),用戶端需部署在一個已配置好kubectl及叢集kubeconfig的機器上。

3. 災備恢複場景

3.1 本叢集

這裡,我們将使用velero備份一個叢集内相關的resource,并在當該叢集出現一些故障或誤操作的時候,能夠快速恢複叢集resource, 首先我們用下面的yaml來部署:

---
apiVersion: v1
kind: Namespace
metadata:
  name: nginx-example
  labels:
    app: nginx

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx-example
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        name: nginx
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: my-nginx
  namespace: nginx-example
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer           

3.1.1 備份

我們可以全量備份,也可以隻備份需要備份的一個namespace,本處隻備份一個namespace:nginx-example

velero backup create nginx-example-backup --include-namespaces nginx-example

Backup request "nginx-example-backup" submitted successfully.
Run `velero backup describe nginx-example-backup` or `velero backup logs nginx-example-backup` for more details.           

我們先記錄下目前namespace下的資源情況

# namespace nginx-example仍然存在
kubectl get ns
NAME            STATUS   AGE
default         Active   2d22h
kube-public     Active   2d22h
kube-system     Active   2d22h
nginx-example   Active   8m34s
velero          Active   120m

# nginx-example下面pod的相關資訊
kubectl get po -n nginx-example -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP             NODE                           NOMINATED NODE
nginx-deployment-5c689d88bb-855h8   1/1     Running   0          2m31s   172.20.0.114   cn-zhangjiakou.192.168.1.144   <none>
nginx-deployment-5c689d88bb-k5j9z   1/1     Running   0          2m31s   172.20.0.115   cn-zhangjiakou.192.168.1.144   <none>

# nginx-example下面deployment的相關資訊
kubectl get deployment -n nginx-example -o wide
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES        SELECTOR
nginx-deployment   2         2         2            2           5m2s   nginx        nginx:1.7.9   app=nginx

# nginx-example下面service的相關資訊
kubectl get svc -n nginx-example -o wide
NAME       TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE     SELECTOR
my-nginx   LoadBalancer   172.21.9.159   47.92.44.156   80:32088/TCP   6m36s   app=nginx           

現在我們模拟一次誤操作導緻namespace nginx-example被誤删

kubectl delete namespaces nginx-example           

3.1.2 恢複

使用velero restore指令來恢複之前的備份

velero  restore create --from-backup nginx-example-backup

Restore request "nginx-example-backup-20190523200227" submitted successfully.
Run `velero restore describe nginx-example-backup-20190523200227` or `velero restore logs nginx-example-backup-20190523200227` for more details.           

我們再來檢查下namespace nginx-example及其下面的資源是否被恢複

# 檢查下namespace nginx-example是否已被建立
kubectl get ns
NAME            STATUS   AGE
default         Active   2d22h
kube-public     Active   2d22h
kube-system     Active   2d22h
nginx-example   Active   68s
velero          Active   112m

# 檢查下pod 
kubectl get po -n nginx-example -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP             NODE                           NOMINATED NODE
nginx-deployment-5c689d88bb-855h8   1/1     Running   0          3m2s   172.20.0.131   cn-zhangjiakou.192.168.1.145   <none>
nginx-deployment-5c689d88bb-k5j9z   1/1     Running   0          3m2s   172.20.0.132   cn-zhangjiakou.192.168.1.145   <none>

# nginx-example下面deployment的相關資訊
kubectl get deployment -n nginx-example -o wide
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES        SELECTOR
nginx-deployment   2         2         2            2           4m52s   nginx        nginx:1.7.9   app=nginx

# nginx-example下面service的相關資訊
kubectl get svc -n nginx-example -o wide
NAME       TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE    SELECTOR
my-nginx   LoadBalancer   172.21.3.239   39.98.8.5     80:30351/TCP   7m9s   app=nginx           

可以看到resource name都保持不變,但是相關的ip,nodeport,LB位址等都會重新配置設定

接下來,我們來做一個實驗,驗證下恢複的形态是什麼樣的:

  1. 額外部署一個tomcat的deployment
    kubectl get deployment -n nginx-example
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   2         2         2            2           3m23s
    tomcat             2         2         2            2           27s           
  2. 做一次restore,觀察下是否會删除掉tomcat這個deployment
    velero  restore create --from-backup nginx-example-backup
    
    kubectl get deployment -n nginx-example
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   2         2         2            2           6m32s
    tomcat             2         2         2            2           3m36s           

可以看到,restore的行為不是覆寫

  1. 接下來,我們把最初backup中存在的nginx删除掉
    kubectl delete deployment nginx-deployment -n nginx-example
    deployment.extensions "nginx-deployment" deleted
    
    kubectl get deployment -n nginx-example
    NAME     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    tomcat   2         2         2            2           6m49s           
  1. 現在再來一次restore,我們知道之前backup中有nginx,沒有tomcat,那restore之後是什麼樣呢?
    velero  restore create --from-backup nginx-example-backup
    
    kubectl get deployment -n nginx-example
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   2         2         2            2           3s
    tomcat             2         2         2            2           8m33s           
  2. 如果我們現在将nginx的image版本更新成latest,那在restore之後是什麼樣呢?
    # 更新nginx的image從1.7.9到latest,并檢視目前的image版本
    kubectl get deployment -n nginx-example -o wide
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES          SELECTOR
    nginx-deployment   2         2         2            2           2m29s   nginx        nginx:latest    app=nginx
    tomcat             2         2         2            2           10m     tomcat       tomcat:latest   app=tomcat
    
    # restore backup
    velero  restore create --from-backup nginx-example-backup
    # 再來看下nginx的image版本,并沒有恢複到最初的版本
    kubectl get deployment -n nginx-example -o wide
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES          SELECTOR
    nginx-deployment   2         2         2            2           3m15s   nginx        nginx:latest    app=nginx
    tomcat             2         2         2            2           11m     tomcat       tomcat:latest   app=tomcat           

結論:velero恢複不是直接覆寫,而是會恢複目前叢集中不存在的resource,已有的resource不會復原到之前的版本,如需要復原,需在restore之前提前删除現有的resource。

3.2 跨叢集

我們現在在阿裡雲深圳region再建立一個k8s叢集(k8s-sz),接下來,我們将驗證下velero跨region跨叢集恢複k8s資源的能力,我們将把前面給張家口叢集建立的備份恢複到一個新的region

3.2.1 恢複

在velero用戶端機器上,将k8s-sz叢集的kubeconfig資訊配置到~/.kube/config

執行如下velero恢複指令進行恢複

velero restore create --from-backup nginx-example-backup           

可以看到namespace恢複了

kubectl get ns
NAME            STATUS   AGE
default         Active   18m
kube-public     Active   18m
kube-system     Active   18m
nginx-example   Active   5m20s
velero          Active   5m47s           

namespace nginx-example下的resource也已恢複

kubectl get po -owide -n nginx-example
NAME                                READY   STATUS    RESTARTS   AGE   IP             NODE                       NOMINATED NODE
nginx-deployment-5c689d88bb-855h8   1/1     Running   0          10m   172.20.0.133   cn-shenzhen.192.168.1.50   <none>
nginx-deployment-5c689d88bb-k5j9z   1/1     Running   0          10m   172.20.0.134   cn-shenzhen.192.168.1.50   <none>           

3.3 進階備份功能

3.3.1 周期性定時備份

可以設定一個周期性定時備份

velero schedule create <SCHEDULE NAME> --schedule "0 7 * * *"           

上面的指令可以以-這樣的命名方式來建立備份對象(restore object)

3.3.2 備份持久資料卷

如需備份恢複持久卷,備份如下:

velero backup create nginx-backup-volume --snapshot-volumes --include-namespaces nginx-example           

該備份會在叢集所在region給雲盤建立快照(目前還不支援NAS和OSS存儲),快照恢複雲盤隻能在同region完成。

恢複指令如下:

velero  restore create --from-backup nginx-backup-volume --restore-volumes           

3.4 删除備份

  1. 方法一,通過指令直接删除
velero delete backups default-backup           
  1. 方法二,設定備份自動過期,在建立備份時,加上TTL參數
velero backup create <BACKUP-NAME> --ttl <DURATION>           

4. 遷移場景

和災備跨叢集恢複場景類似,velero可以幫助我們把一個k8s叢集的resource導出并導入到另外一個叢集,隻要将每個Velero執行個體指向同一個雲對象存儲位置,Velero就可以幫助我們将資源從一個叢集移植到另一個叢集,請注意,Velero不支援跨雲提供商遷移持久卷。目前使用velero遷移叢集功能最完善的場景是在同一個雲廠商的同一個region,可以恢複叢集的應用和資料卷。

  • 在叢集1上做一個備份:
velero backup create <BACKUP-NAME> --snapshot-volumes           
  • 在叢集2上做一個恢複:
velero restore create --from-backup <BACKUP-NAME> --restore-volumes           

5. 總結

velero作為一個免費的開源元件,其能力基本可以滿足容器服務的災備和遷移的場景,推薦使用者将velero日常備份作為運維的一部分,未雨綢缪,防患未然。