Velero備份恢複阿裡雲容器服務ACK
1. 前言
不管是在傳統IT還是新興的雲計算場景下,對業務系統進行例行的備份都是一個非常重要的環節,本文将着重介紹如何使用開源工具
velero給阿裡雲上的ACK k8s叢集進行例行備份,以及如何恢複,該方案可以作為ACK使用者日常運維的一個重要環節。
velero可以幫助我們:
- 災備場景,提供備份恢複k8s叢集的能力
- 遷移場景,提供拷貝叢集資源到其他叢集的能力(複制同步開發,測試,生産環境的叢集配置,簡化環境配置)
2. 環境準備
- 部署ACK kubernetes叢集 ,我們首先在阿裡雲張家口region建立了一個k8s叢集
- 建立OSS Bucket ,在張家口region建立一個OSS bucket用于velero備份
- 下載下傳安裝官方velero用戶端( https://github.com/heptio/velero )
- 安裝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位址等都會重新配置設定
接下來,我們來做一個實驗,驗證下恢複的形态是什麼樣的:
- 額外部署一個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
- 做一次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的行為不是覆寫
- 接下來,我們把最初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
- 現在再來一次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
- 如果我們現在将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 删除備份
- 方法一,通過指令直接删除
velero delete backups default-backup
- 方法二,設定備份自動過期,在建立備份時,加上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日常備份作為運維的一部分,未雨綢缪,防患未然。