一、簡介
Velero 是一款雲原生時代的災難恢復和遷移工具,採用 Go 語言編寫,並在 github 上進行了開源,利用 velero 使用者可以安全的備份、恢復和遷移 Kubernetes 叢集資源和持久卷。
1.1 支援的版本列表
1.2 Velero元件
Velero 元件一共分兩部分,分別是服務端和客戶端。
- 服務端:執行在你 Kubernetes 的叢集中
- 客戶端:是一些執行在本地的命令列的工具,需要已配置好 kubectl 及叢集 kubeconfig 的機器上
1.3 velero備份流程
- velero客戶端呼叫kubernetes API Server建立backup任務
- Backup控制器基於watch機制透過Api Server獲取到備份任務
- Backup控制器開始執行備份動作,會透過請求Api Server獲取到需要備份的資料
- Backup 控制器將獲取到的資料備份到指定的物件儲存server端
1.4 Velero後端儲存
Velero
支援兩種關於後端儲存的CRD
,分別是BackupStorageLocation
和VolumeSnapshotLocation
。
1.4.1 BackupStorageLocation
主要用來定義 Kubernetes 叢集資源的資料存放位置,也就是叢集物件資料,不是 PVC 的資料。主要支援的後端儲存是 S3 相容的儲存,比如:Mino 和阿里雲 OSS 等。
1.4.2 VolumeSnapshotLocation
主要用來給 PV 做快照,需要雲提供商提供外掛。阿里雲已經提供了外掛,這個需要使用 CSI 等儲存機制。你也可以使用專門的備份工具 Restic
,把 PV 資料備份到阿里雲 OSS 中去(安裝時需要自定義選項)。
Restic 是一款 GO 語言開發的資料加密備份工具,顧名思義,可以將本地資料加密後傳輸到指定的倉庫。支援的倉庫有 Local、SFTP、Aws S3、Minio、OpenStack Swift、Backblaze B2、Azure BS、Google Cloud storage、Rest Server。
二、準備儲存外掛
Velero支援很多種儲存外掛,可檢視:https://velero.io/docs/v1.10/supported-providers/獲取外掛資訊,我們這裡使用minio作為S3相容的物件儲存提供程式。您也可以在任意地方部署Minio物件儲存,只需要保證K8S叢集可以訪問到即可。
2.1 準備minio清單
---
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: velero
labels:
app: minio
spec:
selector:
app: minio
ports:
- name: api
port: 9000
protocol: TCP
- name: console
port: 9001
protocol: TCP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: velero
labels:
app: minio
spec:
replicas: 1
serviceName: minio
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: docker.io/bitnami/minio:2023.3.22
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9000
name: api
protocol: TCP
- containerPort: 9001
name: console
protocol: TCP
env:
- name: MINIO_ROOT_USER
value: "minio"
- name: MINIO_ROOT_PASSWORD
value: "minio123"
- name: MINIO_DEFAULT_BUCKETS
value: "velero"
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi
2.2 建立minio應用
# 建立velero名稱空間
$ kubectl create namespace velero
# 建立minio資源
$ kubectl apply -f minio.yaml
# 檢視部署狀態
$ kubectl get sts,pod,svc -n velero
NAME READY AGE
statefulset.apps/minio 1/1 66s
NAME READY STATUS RESTARTS AGE
pod/minio-0 1/1 Running 0 65s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/minio ClusterIP 10.99.223.162 <none> 9000/TCP,9001/TCP 66s
# 開放NodePort埠
$ kubectl patch svc minio -n velero -p '{"spec": {"type": "NodePort"}}'
$ kubectl patch svc minio -n velero --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":9000},{"op": "replace", "path": "/spec/ports/1/nodePort", "value":9001}]'
$ kubectl get svc -n velero
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
minio NodePort 10.99.223.162 <none> 9000:9000/TCP,9001:9001/TCP 140m
透過瀏覽器訪問伺服器IP:9001
,並使用賬號minio
密碼minio123
登入驗證。
三、安裝velero v1.10.2
版本列表:https://github.com/vmware-tanzu/velero/releases
3.1 安裝velero命令程式
$ wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz
$ tar zxf velero-v1.10.2-linux-amd64.tar.gz
$ mv velero-v1.10.2-linux-amd64/velero /usr/bin/
$ velero -h
# 啟用命令補全
$ source <(velero completion bash)
$ velero completion bash > /etc/bash_completion.d/velero
3.2 建立金鑰
$ cat > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
3.3 安裝velero到k8s叢集
$ velero install \
--provider aws \
--image velero/velero:v1.10.2 \
--plugins velero/velero-plugin-for-aws:v1.6.0 \
--bucket velero \
--secret-file ./credentials-velero \
--use-node-agent \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio:9000 \
--wait
# 執行install命令後會建立一系列清單,包括CustomResourceDefinition、Namespace、Deployment等。
# 可使用如下命令檢視執行日誌
$ kubectl logs deployment/velero -n velero
# 檢視velero建立的api物件
$ kubectl api-versions | grep velero
velero.io/v1
# 檢視備份位置
$ velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero Available 2023-03-28 15:45:30 +0800 CST ReadWrite true
選項說明:
--kubeconfig
(可選):指定kubeconfig
認證檔案,預設使用.kube/config
;--provider
:定義外掛提供方;--image
:定義執行velero的映象,預設與velero客戶端一致;--plugins
:指定使用aws s3相容的外掛映象;--bucket
:指定物件儲存Bucket桶名稱;--secret-file
:指定物件儲存認證檔案;--use-node-agent
:建立Velero Node Agent守護程式,託管FSB模組;--use-volume-snapshots
:是否啟使用快照;--namespace
:指定部署的namespace名稱,預設為velero;--backup-location-config
:指定物件儲存地址資訊;
aws外掛與velero版本對應關係:
3.4 解除安裝velero
如果您想從叢集中完全解除安裝Velero,則以下命令將刪除由velero install
建立的所有資源:
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero
四、備份與恢復
備份命令:velero create backup NAME [flags]
backup選項:
--exclude-namespaces stringArray
: 要從備份中排除的名稱空間--exclude-resources stringArray
: 要從備份中排除的資源,如storageclasses.storage.k8s.io
--include-cluster-resources optionalBool[=true]
: 包含叢集資源型別--include-namespaces stringArray
: 要包含在備份中的名稱空間(預設'*')--include-resources stringArray
: 備份中要包括的資源--labels mapStringString
: 給這個備份加上標籤-o, --output string
: 指定輸出格式,支援'table'、'json'和'yaml';-l, --selector labelSelector
: 對指定標籤的資源進行備份--snapshot-volumes optionalBool[=true]
: 對 PV 建立快照--storage-location string
: 指定備份的位置--ttl duration
: 備份資料多久刪掉--volume-snapshot-locations strings
: 指定快照的位置,也就是哪一個公有云驅動
4.1 備份
4.1.1 使用官方案例建立測試應用
$ kubectl apply -f examples/nginx-app/base.yaml
namespace/nginx-example created
deployment.apps/nginx-deployment created
service/my-nginx created
# 檢視資源清單
$ kubectl get all -n nginx-example
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-57d5dcb68-g42mk 1/1 Running 0 41s
pod/nginx-deployment-57d5dcb68-pcc6t 1/1 Running 0 41s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-nginx LoadBalancer 10.96.0.31 <pending> 80:27370/TCP 41s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 2/2 2 2 41s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-57d5dcb68 2 2 2 41s
4.1.2 備份測試應用
$ velero backup create nginx-backup --include-namespaces nginx-example
Backup request "nginx-backup" submitted successfully.
Run `velero backup describe nginx-backup` or `velero backup logs nginx-backup` for more details.
選項:
--include-namespaces
:指定名稱空間--selector
:標籤選擇器,如app=nginx
4.1.3 檢視備份列表
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
nginx-backup Completed 0 0 2023-03-09 09:38:50 +0800 CST 29d default <none>
# 檢視備份詳細資訊
$ velero backup describe nginx-backup
# 檢視備份日誌
$ velero backup logs nginx-backup
登入minio控制檯檢視備份內容
4.1.4 定時備份指南
# 使用cron表示式備份
$ velero schedule create nginx-daily --schedule="0 1 * * *" --include-namespaces nginx-example
# 使用一些非標準的速記 cron 表示式
$ velero schedule create nginx-daily --schedule="@daily" --include-namespaces nginx-example
# 手動觸發定時任務
$ velero backup create --from-schedule nginx-daily
更多cron示例請參考:cron package’s documentation
4.2 恢復
4.2.1 模擬災難
# 刪除nginx-example名稱空間和資源
$ kubectl delete namespace nginx-example
# 檢查是否刪除
$ kubectl get all -n nginx-example
No resources found in nginx-example namespace.
4.2.2 恢復資源
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
nginx-backup Completed 0 0 2023-03-09 09:38:50 +0800 CST 29d default <none>
$ velero restore create --from-backup nginx-backup
Restore request "nginx-backup-20230309095025" submitted successfully.
Run `velero restore describe nginx-backup-20230309095025` or `velero restore logs nginx-backup-20230309095025` for more details.
4.2.3 檢查恢復的資源
$ velero restore get
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
nginx-backup-20230309095025 nginx-backup Completed 2023-03-09 09:50:25 +0800 CST 2023-03-09 09:50:25 +0800 CST 0 1 2023-03-09 09:50:25 +0800 CST <none>
# 檢視詳細資訊
$ velero restore describe nginx-backup-20230309095025
# 檢查資源狀態
$ kubectl get all -n nginx-example
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-57d5dcb68-g42mk 1/1 Running 0 2m19s
pod/nginx-deployment-57d5dcb68-pcc6t 1/1 Running 0 2m19s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-nginx LoadBalancer 10.96.0.204 <pending> 80:31291/TCP 2m19s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 2/2 2 2 2m19s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-57d5dcb68 2 2 2 2m19s
五、專案遷移實戰
5.1、專案介紹
我們將使用Velero
快速完成雲原生應用及PV資料的遷移實踐過程,在本文示例中,我們將A叢集中的一個MOS應用遷移到叢集B中,其中資料備份採用自建Minio物件儲存服務。
5.1.1 環境要求
- 遷移專案最好保證兩個Kubernetes叢集版本一致。
- 為了保證PV資料成功遷移,兩邊需要安裝好相同名字的
StorageClass
。 - 可以自己部署Minio,也可以使用公有云的物件儲存服務,如華為的OBS、阿里的OSS等。
- 本案例將叢集A中app-system名稱空間中的服務及PV資料遷移到叢集B中。
5.1.2 專案環境
角色 | 叢集IP | 叢集版本 | 部署軟體 |
---|---|---|---|
K8S 叢集A | 192.168.1.102 | v1.22.10 | openebs、velero、app-system |
K8S 叢集B | 192.168.1.103 | v1.22.10 | openebs、velero、minio |
5.1.3 專案說明
我們需要將叢集A中 app-system 空間的所有資源和資料全部遷移到叢集B中,該專案包括了deployment
、statefulset
、service
、ingress
、job
、cronjob
、secret
、configmap
、pv
、pvc
。
# 專案清單資訊
$ kubectl get deployment,sts,pvc -n app-system
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hasura-graphql 1/1 1 1 5h27m
deployment.apps/iot-backend 1/1 1 1 5h27m
deployment.apps/iot-gateway 1/1 1 1 5h27m
deployment.apps/iot-history 1/1 1 1 5h27m
deployment.apps/iot-observer 1/1 1 1 5h27m
deployment.apps/app-backend 1/1 1 1 5h27m
deployment.apps/app-frontend 1/1 1 1 5h27m
NAME READY AGE
statefulset.apps/minio 1/1 5h27m
statefulset.apps/mongo 1/1 5h27m
statefulset.apps/postgres 1/1 5h27m
statefulset.apps/rabbitmq 1/1 5h27m
statefulset.apps/redis 1/1 5h27m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/data-minio-0 Bound pvc-950d15a8-20a5-4e5f-8dbf-b904295355bb 50Gi RWO openebs-hostpath 5h27m
persistentvolumeclaim/data-mongo-0 Bound pvc-e435b80e-0370-4100-b223-ca841f24bd5d 50Gi RWO openebs-hostpath 5h27m
persistentvolumeclaim/data-postgres-0 Bound pvc-359ec32a-4bfc-4bc8-8cf3-38322e8ef59b 300Gi RWO openebs-hostpath 5h27m
persistentvolumeclaim/data-redis-0 Bound pvc-da718e0c-992c-4f6e-af44-abb1c7214a9e 2Gi RWO openebs-hostpath 5h27m
persistentvolumeclaim/app-backend Bound pvc-506261a9-6be4-4d95-8807-58201e31a527 10Gi RWO openebs-hostpath 5h27m
5.2 準備物件儲存
按照2.1和2.2的方法在叢集B(192.168.1.103)中建立minio
應用,用來存放備份資料。
$ kubectl get sts,svc -n velero
NAME READY AGE
statefulset.apps/minio 1/1 3h44m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/minio NodePort 10.99.223.162 <none> 9000:9000/TCP,9001:9001/TCP 3h44m
5.3 安裝velero
請確保在叢集A和叢集B中已經安裝好velero客戶端,請參考3.1 安裝velero命令程式
5.3.1 在叢集A中安裝velero服務
$ cat > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
$ velero install \
--provider aws \
--image velero/velero:v1.10.2 \
--plugins velero/velero-plugin-for-aws:v1.6.0 \
--bucket velero \
--secret-file ./credentials-velero \
--use-node-agent \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.1.103:9000 \
--wait
注意:其中S3
的地址指向叢集B(192.168.1.103)的minio物件儲存。
5.3.2 在叢集B種安裝velero服務
$ cat > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
$ velero install \
--provider aws \
--image velero/velero:v1.10.2 \
--plugins velero/velero-plugin-for-aws:v1.6.0 \
--bucket velero \
--secret-file ./credentials-velero \
--use-node-agent \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio:9000 \
--wait
注意:其中S3
的地址指向本叢集minio物件儲存的svc地址。
5.4 備份MOS專案
$ velero backup create app-backup \
--default-volumes-to-fs-backup \
--include-namespaces app-system
Backup request "app-backup" submitted successfully.
Run `velero backup describe app-backup` or `velero backup logs app-backup` for more details.
# 檢視備份狀態
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
app-backup Completed 0 0 2023-03-28 16:34:56 +0800 CST 29d default <none>
--default-volumes-to-fs-backup
:預設將所有PV捲進行備份,詳情檢視官方文件。--include-namespaces
:指定要備份的名稱空間
登入minio控制檯上可以看到備份的檔案:
5.5 恢復到叢集B
# 到叢集B中檢視備份資源
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
app-backup Completed 0 0 2023-03-28 16:41:55 +0800 CST 29d default <none>
# 執行恢復命令
$ velero restore create --from-backup app-backup
Restore request "app-backup-20230328164601" submitted successfully.
Run `velero restore describe app-backup-20230328164601` or `velero restore logs app-backup-20230328164601` for more details.
# 檢視恢復任務
$ velero restore get
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
app-backup-20230328164601 app-backup Completed 2023-03-28 16:46:01 +0800 CST 2023-03-28 17:01:26 +0800 CST 0 30 2023-03-28 16:46:01 +0800 CST <none>
5.6 驗證服務和資料
$ kubectl get deploy,sts,svc,pvc -n app-system
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hasura-graphql 1/1 1 1 29m
deployment.apps/iot-backend 1/1 1 1 29m
deployment.apps/iot-gateway 1/1 1 1 29m
deployment.apps/iot-history 1/1 1 1 29m
deployment.apps/iot-observer 1/1 1 1 29m
deployment.apps/app-backend 1/1 1 1 29m
deployment.apps/app-frontend 1/1 1 1 29m
NAME READY AGE
statefulset.apps/minio 1/1 29m
statefulset.apps/mongo 1/1 29m
statefulset.apps/postgres 1/1 29m
statefulset.apps/rabbitmq 1/1 29m
statefulset.apps/redis 1/1 29m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hasura-graphql ClusterIP 10.107.231.148 <none> 8080/TCP 29m
service/iot-backend ClusterIP 10.98.78.23 <none> 3000/TCP 29m
service/iot-gateway ClusterIP 10.108.211.114 <none> 1880/TCP 29m
service/iot-history ClusterIP 10.98.217.234 <none> 3000/TCP 29m
service/iot-observer ClusterIP 10.105.75.200 <none> 3010/TCP 29m
service/minio ClusterIP 10.97.14.151 <none> 9000/TCP,9001/TCP 29m
service/mongo ClusterIP 10.97.212.84 <none> 27017/TCP 29m
service/app-backend ClusterIP 10.107.16.116 <none> 5959/TCP 29m
service/app-frontend ClusterIP 10.100.136.90 <none> 80/TCP,443/TCP 29m
service/postgres ClusterIP 10.101.235.245 <none> 5432/TCP,9187/TCP 29m
service/rabbitmq ClusterIP 10.108.29.67 <none> 15672/TCP,5672/TCP 29m
service/redis ClusterIP 10.101.105.81 <none> 6379/TCP,9121/TCP 29m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/data-minio-0 Bound pvc-ca5c63bf-9aaa-4755-ad8f-35718f51decf 50Gi RWO openebs-hostpath 29m
persistentvolumeclaim/data-mongo-0 Bound pvc-03203801-e339-44ee-bfb4-b196808c7cc5 50Gi RWO openebs-hostpath 29m
persistentvolumeclaim/data-postgres-0 Bound pvc-e2f2593e-5869-420c-bd39-54ce01dfa63f 300Gi RWO openebs-hostpath 29m
persistentvolumeclaim/data-redis-0 Bound pvc-a8e4445c-c6b5-483b-8b18-9d650daf35cc 2Gi RWO openebs-hostpath 29m
persistentvolumeclaim/app-backend Bound pvc-2b2f9747-a020-4a16-9975-2491457c4032 10Gi RWO openebs-hostpath 29m