使用 Velero 進行集羣備份與遷移
摘要:近日正好有 k8s 集羣服務遷移服務的需求,使用 Velero 完成了服務的遷移,同時也每日進行集羣資源備份,其能力可以滿足容器服務的災備和遷移場景,實測可用,現已運行在所有的 k8s 集羣。Velero 將集羣資源保存在對象存儲中,默認情況下可以使用 AWS 、 Azure 、 GCP 的對象存儲,同時也給出了插件功能用來拓展其他平臺的存儲,這裏我們用到的就是阿里雲的對象存儲 OSS,阿里雲也提供了 Velero 的插件,用於將備份存儲到 OSS 中。
前言
在近日的一個風和日麗的下午,正在快樂的寫 bug 時,突然間釘釘就被 call 爆了,原來是 k8s 測試集羣的一個 namespace 突然不見了。這個 namespace 裏面有 60 多個服務,瞬間全部沒有了……雖然得益於我們的 CI/CD 系統,這些服務很快都重新部署並正常運行了,但是如果在生產環境,那後果就是不可想象的了。在排查這個問題發生的原因的同時,集羣資源的災備和恢復功能就提上日程了,這時 Velero 就出現了。
Velero
Velero 是 VMWare 開源的 k8s 集羣備份、遷移工具。可以幫助我們完成 k8s 的例行備份工作,以便在出現上面問題的時候可以快速進行恢復。同時也提供了集羣遷移功能,可以將 k8s 資源遷移到其他 k8s 集羣的功能。Velero 將集羣資源保存在對象存儲中,默認情況下可以使用 AWS 、 Azure 、 GCP 的對象存儲,同時也給出了插件功能用來拓展其他平臺的存儲,這裏我們用到的就是阿里雲的對象存儲 OSS,阿里雲也提供了 Velero 的插件,用於將備份存儲到 OSS 中。下面我就介紹一下如何在阿里雲容器服務 ACK 使用 Velero 完成備份和遷移。
Velero 地址: https://github.com/vmware-tanzu/velero
ACK 插件地址: https://github.com/AliyunContainerService/velero-plugin
下載 Velero 客戶端
Velero 由客戶端和服務端組成,服務器部署在目標 k8s 集羣上,而客戶端則是運行在本地的命令行工具。
- 前往 Velero 的 Release 頁面 下載客戶端,直接在 GitHub 上下載即可
- 解壓 release 包
- 將 release 包中的二進制文件
velero
移動到$PATH
中的某個目錄下 - 執行
velero -h
測試
創建 OSS bucket
創建一個 OSS bucket 用於存儲備份文件,這裏也可以用已有的 bucket,之後會在 bucket 中創建 backups
、 metadata
、 restores
三個目錄,這裏建議在已有的 bucket 中創建一個子目錄用於存儲備份文件。
創建 OSS 的時候一定要選對區域,要和 ACK 集羣在同一個區域,存儲類型和讀寫權限選擇 標準存儲 和 私有 :
創建阿里雲 RAM 用戶
這裏需要創建一個阿里雲 RAM 的用戶,用於操作 OSS 以及 ACK 資源。
-
新建權限策略
策略內容:
{ "Version": "1", "Statement": [ { "Action": [ "ecs:DescribeSnapshots", "ecs:CreateSnapshot", "ecs:DeleteSnapshot", "ecs:DescribeDisks", "ecs:CreateDisk", "ecs:Addtags", "oss:PutObject", "oss:GetObject", "oss:DeleteObject", "oss:GetBucket", "oss:ListObjects" ], "Resource": [ "*" ], "Effect": "Allow" } ] }
-
新建用戶
在新建用戶的時候要選擇
編程訪問
,來獲取AccessKeyID
和AccessKeySecret
,這裏請創建一個新用於用於備份,不要使用老用戶的 AK 和 AS。
部署服務端
-
拉取 Velero 插件 到本地
git clone https://github.com/AliyunContainerService/velero-plugin
-
配置修改
-
修改
install/credentials-velero
文件,將新建用戶中獲得的AccessKeyID
和AccessKeySecret
填入,這裏的 OSS EndPoint 爲之前 OSS 的訪問域名( 注:這裏需要選擇外網訪問的 EndPoint。 ):ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET> ALIBABA_CLOUD_OSS_ENDPOINT=<ALIBABA_CLOUD_OSS_ENDPOINT>
-
修改
install/01-velero.yaml
,將 OSS 配置填入:--- apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: labels: component: velero name: default namespace: velero spec: config: {} objectStorage: bucket: <ALIBABA_CLOUD_OSS_BUCKET> # OSS bucket 名稱 prefix: <OSS_PREFIX> # bucket 子目錄 provider: alibabacloud --- apiVersion: velero.io/v1 kind: VolumeSnapshotLocation metadata: labels: component: velero name: default namespace: velero spec: config: region: <REGION> # 地域,如果是華東2(上海),則爲 cn-shanghai provider: alibabacloud
-
k8s 部署 Velero 服務
# 新建 namespace kubectl create namespace velero # 部署 credentials-velero 的 secret kubectl create secret generic cloud-credentials --namespace velero --from-file cloud=install/credentials-velero # 部署 CRD kubectl apply -f install/00-crds.yaml # 部署 Velero kubectl apply -f install/01-velero.yaml
-
測試 Velero 狀態
$ velero version Client: Version: v1.1.0 Git commit: a357f21aec6b39a8244dd23e469cc4519f1fe608 Server: Version: v1.1.0
可以看到 Velero 的客戶端和服務端已經部署成功。
-
服務端清理
在完成測試或者需要重新安裝時,執行如下命令進行清理:
kubectl delete namespace/velero clusterrolebinding/velero kubectl delete crds -l component=velero
-
備份測試
velero-plugin
項目中已經給出 example
用於測試備份。
-
部署測試服務
kubectl apply -f examples/base.yaml
-
對
nginx-example
所在的 namespace 進行備份velero backup create nginx-backup --include-namespaces nginx-example --wait
-
模擬 namespace 被誤刪
kubectl delete namespaces nginx-example
-
使用 Velero 進行恢復
velero restore create --from-backup nginx-backup --wait
集羣遷移
遷移方法同備份,在備份後切換集羣,在新集羣恢復備份即可。
高級用法
-
定時備份
對集羣資源進行定時備份,則可在發生意外的情況下,進行恢復(默認情況下,備份保留 30 天)。
# 每日1點進行備份 velero create schedule <SCHEDULE NAME> --schedule="0 1 * * *" # 每日1點進行備份,備份保留48小時 velero create schedule <SCHEDULE NAME> --schedule="0 1 * * *" --ttl 48h # 每6小時進行一次備份 velero create schedule <SCHEDULE NAME> --schedule="@every 6h" # 每日對 web namespace 進行一次備份 velero create schedule <SCHEDULE NAME> --schedule="@every 24h" --include-namespaces web
定時備份的名稱爲:
<SCHEDULE NAME>-<TIMESTAMP>
,恢復命令爲:velero restore create --from-backup <SCHEDULE NAME>-<TIMESTAMP>
。 -
備份刪除
直接執行命令進行刪除
velero delete backups <BACKUP_NAME>
-
備份資源查看
備份查看
velero backup get
查看定時備份
velero schedule get
查看可恢復備份
velero restore get
-
備份排除項目
可爲資源添加指定標籤,添加標籤的資源在備份的時候被排除。
# 添加標籤 kubectl label -n <ITEM_NAMESPACE> <RESOURCE>/<NAME> velero.io/exclude-from-backup=true # 爲 default namespace 添加標籤 kubectl label -n default namespace/default velero.io/exclude-from-backup=true
問題彙總
時區問題
進行定時備份時,發現備份使用的事 UTC 時間,並不是本地時間,經過排查後發現是 velero
鏡像的時區問題,在調整後就會正常定時備份了,這裏我重新調整了時區,直接調整鏡像就好,修改 install/01-velero.yaml
文件,將鏡像替換爲 registry-vpc.cn-shanghai.aliyuncs.com/keking/velero:latest
。
--- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: velero namespace: velero spec: replicas: 1 selector: matchLabels: deploy: velero template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: "8085" prometheus.io/scrape: "true" labels: component: velero deploy: velero spec: serviceAccountName: velero containers: - name: velero # sync from gcr.io/heptio-images/velero:latest image: registry-vpc.cn-shanghai.aliyuncs.com/keking/velero:latest # 修復時區後的鏡像 imagePullPolicy: IfNotPresent command: - /velero args: - server - --default-volume-snapshot-locations=alibabacloud:default env: - name: VELERO_SCRATCH_DIR value: /scratch - name: ALIBABA_CLOUD_CREDENTIALS_FILE value: /credentials/cloud volumeMounts: - mountPath: /plugins name: plugins - mountPath: /scratch name: scratch - mountPath: /credentials name: cloud-credentials initContainers: - image: registry.cn-hangzhou.aliyuncs.com/acs/velero-plugin-alibabacloud:v1.2 imagePullPolicy: IfNotPresent name: velero-plugin-alibabacloud volumeMounts: - mountPath: /target name: plugins volumes: - emptyDir: {} name: plugins - emptyDir: {} name: scratch - name: cloud-credentials secret: secretName: cloud-credentials
版本問題
截止發稿時,Velero 已經發布了 v1.2.0 版本,目前 ACK 的 Velero 的插件還未升級。
結語
近日正好有 k8s 集羣服務遷移服務的需求,使用 Velero 完成了服務的遷移,同時也每日進行集羣資源備份,其能力可以滿足容器服務的災備和遷移場景,實測可用,現已運行在所有的 k8s 集羣。