您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何使用Velero跨云平臺遷移集群資源到TKE,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Velero 是一個非常強大的開源工具,可以安全地備份和還原,執行災難恢復以及遷移Kubernetes群集資源和持久卷,可以在 TKE 平臺上使用 Velero 備份、還原和遷移集群資源,關于如何使用請參閱 使用對象存儲 COS 作為 Velero 存儲實現集群資源備份和還原 和 在 TKE 中使用 Velero 遷移復制集群資源,本文將介紹如何使用 Velero 將自建或其他云平臺 Kubernetes 集群無縫遷移到 TKE 平臺。
架構原理與使用 Velero 遷移復制集群資源 過程的原理類似,遷移集群和被遷移集群都安裝 Velero 實例,且指定同一個騰訊云 COS 后端存儲,被遷移集群按需執行備份,目標集群按需還原集群資源實現資源遷移。不同的是,自建或其他云平臺的集群資源遷移到 TKE 時,需要考慮和解決因跨平臺導致集群環境差異問題,幸運的是,Velero 提供了很多實用的備份和還原策略幫助我們解決這些問題,后面的遷移示例會介紹如何更好的利用和使用它們。
已有自建或其他云平臺 Kubernetes 集群(以下稱作集群 A ),且集群版本為 1.10 以上。
已創建遷移目標的 TKE 集群(以下稱作集群 B ),創建 TKE 集群請參閱 創建集群。
集群 A 和 集群 B 都需要安裝 Velero 實例(1.5 版本以上),并且共用同一個騰訊云 COS 存儲桶作為 Velero 后端存儲,安裝步驟請參閱 配置存儲和安裝 Velero 。
確保鏡像資源在遷移后可以正常拉取。
確保兩個集群的 K8S 版本的 API 兼容,最好是相同版本。
在遷移工作進行前,首先應該理清遷移思路,制定詳細的遷移計劃,遷移過程大概需要考慮下面幾點:
篩選分析需要遷移哪些集群資源,不需要遷移哪些集群資源
根據實際情況篩選分類出需要遷移資源清單和不需要遷移的資源清單。
根據業務場景考慮是否需要自定義一些 Hook 操作
需要考慮在備份集群資源時,是否需要在備份期間執行 備份 Hooks ,比如需要將正在運行的應用的內存數據落盤場景。
類似的,在還原(遷移)集群資源時,是否需要在還原期間執行 還原 Hooks ,比如需要在還原前做一些初始化工作。
按需編寫備份和還原的命令或資源清單
根據篩選歸類的資源清單編寫備份和還原策略,推薦在復雜場景下使用創建資源清單的方式來執行備份和還原, YAML 資源清單比較直觀且方便維護,參數指定的方式可以在簡單遷移場景或測試時使用。
處理跨云平臺資源的差異性
由于是跨云平臺,動態創建 PVC 的存儲類等關系可能不同,需要提前規劃動態 PVC/PV 存儲類關系是否需要重新映射,需在在還原操作前,創建相關映射的 ConfigMap
配置。如果需要解決更加個性化的差異,可以手動修改備份后的資源清單解決。
操作完成后核查遷移資源
檢查校驗遷移的集群資源是否符合預期且數據完整可用。
接下來將演示將某云平臺集群 A 中的資源遷移到 TKE 集群 B 中的操作步驟,其中涉及到 Velero 備份和還原實用基礎知識,如不了解請先移步文章末尾【 Velero 備份/還原實用知識】 查看。
在某云平臺集群 A 中部署 Velero 示例中含有 PVC 的 Nginx 工作負載,為了方便起見直接使用動態存儲類來創建 PVC 和 PV ,首先查看當前集群支持的動態存儲類信息:
# 獲取當前集群支持的存儲類信息,其中 xxx-StorageClass 為存儲類代名,xxx-Provider 為提供商代名,下同。 [root@iZj6c3vzs170hmeiu98h6aZ ~]# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE xxx-StorageClass xxx-Provider Delete Immediate true 3d3h ...
使用集群中存儲類名為 "xxx-StorageClass" 的存儲類來動態創建 ,修改 with-pv.yaml 的 PVC 資源清單如下圖:
... --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nginx-logs namespace: nginx-example labels: app: nginx spec: # Optional: 修改 PVC 的存儲類的值為某云平臺 storageClassName: xxx-StorageClass accessModes: - ReadWriteOnce resources: requests: storage: 20Gi # 由于該云平臺限制存儲最小為20Gi,本示例需要同步修改此值為20Gi ...
修改完成后應用示例中的 YAML 創建如下的集群資源(nginx-example命名空間):
[root@iZj6c3vzs170hmeiu98h6aZ nginx-app]# kubectl apply -f with-pv.yaml namespace/nginx-example created persistentvolumeclaim/nginx-logs created deployment.apps/nginx-deployment created service/my-nginx created
創建出來的 PVC "nginx-logs" 已掛載給 nginx 容器的 /var/log/nginx
目錄作為服務的日志存儲,本示例在瀏覽器測試訪問 Nginx 服務,給掛載的 PVC 生產一些日志數據(以便后續還原后做數據比對)。
# 查看測試產生的 Nginx 日志大小,當前為 84 K [root@iZj6c8ttj5dmmrs75yb7ybZ ~]# kubectl exec -it nginx-deployment-5ccc99bffb-6nm5w bash -n nginx-example kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] Defaulting container name to nginx. Use 'kubectl describe pod/nginx-deployment-5ccc99bffb-6nm5w -n nginx-example' to see all of the containers in this pod root@nginx-deployment-5ccc99bffb-6nm5w:/# du -sh /var/log/nginx/ 84K /var/log/nginx/ # 查看 accss.log 和 error.log 前兩條日志 root@nginx-deployment-5ccc99bffb-6nm5w:/# head -n 2 /var/log/nginx/access.log 192.168.0.73 - - [29/Dec/2020:03:02:31 +0000] "GET /?spm=5176.2020520152.0.0.22d016ddHXZumX HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-" 192.168.0.73 - - [29/Dec/2020:03:02:32 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://47.242.233.22/?spm=5176.2020520152.0.0.22d016ddHXZumX" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-" root@nginx-deployment-5ccc99bffb-6nm5w:/# head -n 2 /var/log/nginx/error.log 2020/12/29 03:02:32 [error] 6#6: *597 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.0.73, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "47.242.233.22", referrer: "http://47.242.233.22/?spm=5176.2020520152.0.0.22d016ddHXZumX" 2020/12/29 03:07:21 [error] 6#6: *1172 open() "/usr/share/nginx/html/0bef" failed (2: No such file or directory), client: 192.168.0.73, server: localhost, request: "GET /0bef HTTP/1.0"
使用下面命令輸出當前集群中所有的資源清單列表:
kubectl api-resources --verbs=list -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found --all-namespaces
也可以根據資源是否區分命名空間需要縮小輸出的資源范圍:
查看不區分命名空間的資源清單列表:
kubectl api-resources --namespaced=false --verbs=list -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found
查看區分命名空間的資源清單列表:
kubectl api-resources --namespaced=true --verbs=list -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found --all-namespaces
可以根據實際情況篩選出需要被遷移的資源清單,本示例將直接從該云平臺遷移 "nginx-example" 命名空間下 Nginx 工作負載相關的資源到 TKE 平臺,涉及資源如下所示:
[root@iZj6c3vzs170hmeiu98h6aZ ~]# kubectl get all -n nginx-example NAME READY STATUS RESTARTS AGE pod/nginx-deployment-5ccc99bffb-tn2sh 2/2 Running 0 2d19h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-nginx LoadBalancer 172.21.1.185 x.x.x.x 80:31455/TCP 2d19h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 1/1 1 1 2d19h NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5ccc99bffb 1 1 1 2d19h [root@iZj6c3vzs170hmeiu98h6aZ ~]# kubectl get pvc -n nginx-example NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nginx-logs Bound d-j6ccrq4k1moziu1l6l5r 20Gi RWO xxx-StorageClass 2d19h [root@iZj6c3vzs170hmeiu98h6aZ ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE d-j6ccrq4k1moziu1l6l5r 20Gi RWO Delete Bound nginx-example/nginx-logs xxx-StorageClass 2d19h
本示例在 with-pv.yaml 中已經配置了備份 Nginx 工作負載前將文件系統設置為只讀,在備份后恢復讀寫的 Hook 策略,如下 YAML 所示:
... annotations: # 備份 Hook 策略的注解表示:在開始備份之前將 nginx 日志目錄設置為只讀模式,備份完成后恢復讀寫模式 pre.hook.backup.velero.io/container: fsfreeze pre.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--freeze", "/var/log/nginx"]' post.hook.backup.velero.io/container: fsfreeze post.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--unfreeze", "/var/log/nginx"]' spec: volumes: - name: nginx-logs persistentVolumeClaim: claimName: nginx-logs containers: - image: nginx:1.17.6 name: nginx ports: - containerPort: 80 volumeMounts: - mountPath: "/var/log/nginx" name: nginx-logs readOnly: false - image: ubuntu:bionic name: fsfreeze securityContext: privileged: true volumeMounts: - mountPath: "/var/log/nginx" name: nginx-logs ...
接下來根據實際情況編寫備份和還原策略,開始對該云平臺的 Nginx 工作負載相關資源進行遷移。
本示例創建如下 YAML 來備份想要遷移的資源:
apiVersion: velero.io/v1 kind: Backup metadata: name: migrate-backup # 必須得是 velero 安裝的命名空間 namespace: velero spec: # 僅包含 nginx-example 命名空間的資源 includedNamespaces: - nginx-example # 包含不區分命名空間的資源 includeClusterResources: true # 備份數據存儲位置指定 storageLocation: default # 卷快照存儲位置指定 volumeSnapshotLocations: - default # 使用 restic 備份卷 defaultVolumesToRestic: true
執行備份過程如下所示, 當備份狀態為 "Completed" 且 errors 數為 0 時表示備份過程完整無誤:
[root@iZj6c8ttj5dmmrs75yb7ybZ ~]# kubectl apply -f backup.yaml backup.velero.io/migrate-backup created [root@iZj6c8ttj5dmmrs75yb7ybZ ~]# velero backup get NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR migrate-backup InProgress 0 0 2020-12-29 19:24:12 +0800 CST 29d default <none> [rootftiZi6c8tti5dmmrs75yb7vbZ ~1# velero backup get NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR migrate-backup Completed 0 0 2020-12-29 19:24:28 +0800 CST 29d default <none>
備份完成后,臨時將備份存儲位置更新為只讀模式(非必須,這可以防止在還原過程中 Velero 在備份存儲位置中創建或刪除備份對象):
kubectl patch backupstoragelocation default --namespace velero \ --type merge \ --patch '{"spec":{"accessMode":"ReadOnly"}}'
由于使用的動態存儲類有差異,這里需要如下所示的 ConfigMap 為持久卷 "nginx-logs" 創建動態存儲類名映射:
apiVersion: v1 kind: ConfigMap metadata: name: change-storage-class-config namespace: velero labels: velero.io/plugin-config: "" velero.io/change-storage-class: RestoreItemAction data: # 存儲類名映射到騰訊云動態存儲類 cbs xxx-StorageClass: cbs
應用上述的 ConfigMap
配置:
[root@VM-20-5-tlinux ~]# kubectl apply -f cm-storage-class.yaml configmap/change-storage-class-config created
Velero 備份的資源清單 以 json
格式存放在對象存儲中,如果有更加個性化的遷移需求,可以直接下載備份文件并自定義修改,本示例將為 Nginx 的 Deployment 資源自定義添加一個 "jokey-test:jokey-test" 注解,修改過程如下:
jokey@JOKEYLI-MB0 Downloads % mkdir migrate-backup # 解壓備份文件 jokey@JOKEYLI-MB0 Downloads % tar -zxvf migrate-backup.tar.gz -C migrate-backup # 編輯修改想要自定義的資源, 本示例為 nginx 的 Deployment 資源添加 "jokey-test":"jokey-test" 的注解項 jokey@JOKEYLI-MB0 migrate-backup % cat resources/deployments.apps/namespaces/nginx-example/nginx-deployment.json {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"jokey-test":"jokey-test",... # 重新打包修改后的備份文件 jokey@JOKEYLI-MB0 migrate-backup % tar -zcvf migrate-backup.tar.gz *
完成自定義修改并重新打包后上傳替換原有備份文件:
本示例應用如下所示的資源清單執行還原操作(遷移):
apiVersion: velero.io/v1 kind: Restore metadata: name: migrate-restore namespace: velero spec: backupName: migrate-backup includedNamespaces: - nginx-example # 按需填寫需要恢復的資源類型,nginx-example 命名空間下沒有想要排除的資源,所以這里直接寫 '*' includedResources: - '*' includeClusterResources: null # 還原時不包含的資源,這里額外排除 StorageClasses 資源類型。 excludedResources: - storageclasses.storage.k8s.io # 使用 labelSelector 選擇器選擇具有特定 label 的資源,由于此示例中無須再使用 label 選擇器篩選,這里先注釋。 # labelSelector: # matchLabels: # app: nginx # 設置命名空間關系映射策略 namespaceMapping: nginx-example: default restorePVs: true
執行還原過程如下所示, 當還原狀態顯示為 "Completed" 且 "errors" 數為 0 時表示還原過程完整無誤:
[root@VM-20-5-tlinux ~]# kubectl apply -f restore.yaml restore.velero.io/migrate-restore created [root@VM-20-5-tlinux ~]# velero restore get NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR migrate-restore migrate-backup Completed 2021-01-12 20:39:14 +0800 CST 2021-01-12 20:39:17 +0800 CST 0 0 2021-01-12 20:39:14 +0800 CST <none>
首先查看被遷移的資源的運行狀態是否正常。
# 由于在還原時指定了 "nginx-example" 命名空間映射到 "default" 命名空間,所以還原的資源將運行在 "default" 命名空間下 [root@VM-20-5-tlinux ~]# kubectl get all -n default NAME READY STATUS RESTARTS AGE pod/nginx-deployment-5ccc99bffb-6nm5w 2/2 Running 0 49s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-user LoadBalancer 172.16.253.216 10.0.0.28 443:30060/TCP 8d service/kubernetes ClusterIP 172.16.252.1 <none> 443/TCP 8d service/my-nginx LoadBalancer 172.16.254.16 x.x.x.x 80:30840/TCP 49s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 1/1 1 1 49s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-5ccc99bffb 1 1 1 49s
從上面可以看出被遷移的資源的運行狀態都是正常的,接下來核查設置的還原策略是否成功。
核查動態存儲類名映射是否正確:
# 可以看到 PVC/PV 的存儲類已經是 "cbs" 了,說明存儲類映射成功。 [root@VM-20-5-tlinux ~]# kubectl get pvc -n default NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nginx-logs Bound pvc-bcc17ccd-ec3e-4d27-bec6-b0c8f1c2fa9c 20Gi RWO cbs 55s [root@VM-20-5-tlinux ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-bcc17ccd-ec3e-4d27-bec6-b0c8f1c2fa9c 20Gi RWO Delete Bound default/nginx-logs cbs 57s
查看還原前為 "deployment.apps/nginx-deployment" 自定義添加的 "jokey-test" 注解是否成功:
# 獲取注解"jokey-test"成功,說明自定義修改資源成功。 [root@VM-20-5-tlinux ~]# kubectl get deployment.apps/nginx-deployment -o custom-columns=annotations:.metadata.annotations.jokey-test annotations jokey-test
從上述查看資源運行狀態可以看出命名空間映射配置也是成功的。
檢查工作負載掛載的 PVC 數據是否成功遷移:
# 查看掛載的 PVC 數據目錄中的數據大小,顯示為 88K 比遷移前多,原因是騰訊云 CLB 主動發起健康檢查產生了一些日志。 [root@VM-20-5-tlinux ~]# kubectl exec -it nginx-deployment-5ccc99bffb-6nm5w -n default -- bash Defaulting container name to nginx. Use 'kubectl describe pod/nginx-deployment-5ccc99bffb-6nm5w -n default' to see all of the containers in this pod. root@nginx-deployment-5ccc99bffb-6nm5w:/# du -sh /var/log/nginx 88K /var/log/nginx # 查看前兩條日志信息,和遷移前一致,大致說明 PVC 數據沒丟失 root@nginx-deployment-5ccc99bffb-6nm5w:/# head -n 2 /var/log/nginx/access.log 192.168.0.73 - - [29/Dec/2020:03:02:31 +0000] "GET /?spm=5176.2020520152.0.0.22d016ddHXZumX HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-" 192.168.0.73 - - [29/Dec/2020:03:02:32 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://47.242.233.22/?spm=5176.2020520152.0.0.22d016ddHXZumX" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-" root@nginx-deployment-5ccc99bffb-6nm5w:/# head -n 2 /var/log/nginx/error.log 2020/12/29 03:02:32 [error] 6#6: *597 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.0.73, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "47.242.233.22", referrer: "http://47.242.233.22/?spm=5176.2020520152.0.0.22d016ddHXZumX" 2020/12/29 03:07:21 [error] 6#6: *1172 open() "/usr/share/nginx/html/0bef" failed (2: No such file or directory), client: 192.168.0.73, server: localhost, request: "GET /0bef HTTP/1.0"
綜上所述,此示例成功遷移某云平臺集群 A 的 Nginx ( nginx-example 命名空間)工作負載相關資源和數據到 TKE 集群 B (default 命名空間)中。
本示例講解和演示了常見的集群資源遷移到 TKE 的思路和方法步驟,若在實際遷移過程中遇到未覆蓋到的場景時,歡迎咨詢和討論遷移解決方案。
velero 提供了許多非常實用的備份和還原策略,以下作簡要梳理:
當不使用任何篩選選項時,Velero 會將所有對象包括在備份或還原操作中,在備份和還原時可以指定參數按需過濾資源:
包含關系的過濾參數:
不包含關系的過濾參數:
詳情請參閱 資源過濾。
--exclude-namespaces
:指定要排除的命名空間列表
--exclude-resources
:指定要排除的資源對象列表。
velero.io/exclude-from-backup=true
:此配置項為資源對象配置 label 屬性,添加了此 label 配置項的資源對象將會排除在外。
--include-resources
:指定要包含的資源對象列表。
--include-namespaces
:指定要包含的命名空間列表。
--include-cluster-resources
:指定是否要包含集群的資源。
--selector
:指定包含與標簽選擇器匹配的資源。
在備份期間執行一些 Hook 操作,比如需要在在備份前將內存數據落盤,詳情請參閱 備份 Hooks 。
在還原期間執行一些 Hook 操作,比如在還原前判斷組件依賴是否可用,詳情請參閱 還原 Hooks 。
在還原時配置 PVC/PV 卷相關映射關系配置:
詳情請參閱 還原參考。
配置 PV / PVC 存儲類映射。
配置 PVC 綁定節點映射。
Restic 備份卷配置
從 1.5 版本開始,Velero 默認使用 Restic 備份所有 pod 卷,而不必單獨注釋每個 pod,所以推薦使用 Velero 1.5 以上版本。
在 1.5 版本以前, Velero 使用 restic 在備份卷時, Restic 有兩種方式發現需要備份的 Pod卷:
備份完成后可以查看備份卷信息:
kubectl -n velero get podvolumebackups -l velero.io/backup-name=<YOUR_BACKUP_NAME> -o yaml
還原完成后可以查看還原卷信息:
kubectl -n velero get podvolumerestores -l velero.io/restore-name=<YOUR_RESTORE_NAME> -o yaml
使用的Pod卷備份選擇包含注解(默認):
kubectl -n <YOUR_POD_NAMESPACE> annotate <pod/YOUR_POD_NAME> backup.velero.io/backup-volumes=<YOUR_VOLUME_NAME_1,YOUR_VOLUME_NAME_2,...>
使用的 Pod 卷備份選擇不包含注解:
kubectl -n <YOUR_POD_NAMESPACE> annotate <pod/YOUR_POD_NAME> backup.velero.io/backup-volumes-excludes=<YOUR_VOLUME_NAME_1,YOUR_VOLUME_NAME_2,...>
關于如何使用Velero跨云平臺遷移集群資源到TKE就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。