備份恢復阿里雲容器服務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日常備份作爲運維的一部分,未雨綢繆,防患未然。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章