使用 Velero 輕鬆在地端與雲端之間來回橫跳

使用 Velero 輕鬆在地端與雲端之間來回橫跳

今天要來跟大家介紹一個 Kubernetes 上的備份工具 Velero,他是一款可以幫你備份集群中多個 Namespace 的資源、PV 的資料甚至是 Pod 中 EmptyDir 裡的資料也可以備份,它支援了很多種 Object Storage 作為儲存備份的後端,並能設定定時備份、管理備份生命週期以及自動刪除過時的備份等方便功能。

工作原理

Velero Docs - How Velero Works

細節原理能參考上方官方文件,我們透過 Velero 的 CLI 工具下達備份或是還原指令,實際上是在 Kubernetes 中創建了 Velero 的 CRD,而 Velero Controller 看到我們創建的 CRD 之後會做對應的操作,如下圖。

例如:把我們指定的 Namespace 中的資源打包上傳到雲端 Object Storage 或是呼叫雲供應商的 API 為你的 PV 建立快照,又或是你的 Pod 掛的是一些自建的 Storage Provider
如:Longhorn 甚至是 emptyDir,Velero 也能透過裝在每一台 Node 的 Agent 透過 HostPath /var/lib/kubelet/pods 取得 Pod 中的檔案打包後上傳備份。

Velero Docs - Providers

上面這個官方文件則是被支援作為備份儲存後端的 Object Storage 常見的三大公有雲都有支援,甚至是開源 Minio 這套也有支援。

應用案例

Velero 在這些場合下特別的實用:

  1. 集群災難回覆
    有人手賤刪 Namespace, Cluster
  2. 快速搭建測試、備用環境
    從生產環境複製成測試集群或是複製同樣的集群為你的 Cluster Infra 變更準備藍綠部屬
  3. 沒有 GitOps 的情況下做集群遷移
    我要從地端遷移到雲端或是從 AWS 遷移到 GCP

安裝

這篇文章會以上述第三個案例來做示範,我需要把我安裝在自己家裡 Server Kubernetes 中的個人網站,暫時遷移到 GCP。

GCP 資源準備

GitHub - vmware-tanzu/velero-plugin-for-gcp: Plugins to support Velero on Google Cloud Platform (GCP)
Plugins to support Velero on Google Cloud Platform (GCP) - GitHub - vmware-tanzu/velero-plugin-for-gcp: Plugins to support Velero on Google Cloud Platform (GCP)

依照我的需求是會需要使用 GCP 上的 GCS 作為我的儲存後端,除此之外依照上面這個 GCP Provider 的文件要先準備一些雲端資源,有 Service Account, GCS, 相關的權限設定等,我這邊會用 Terraform 來建立相關的資源。

Terraform 參考以下資源說明頁:

上面是寫好的範例,可以直接拿去用,會產生對應的資源,並輸出 Service Account 的憑證。下面是部屬的指令,照著做就可以了,不會安裝使用 gcloud 和 terrafrom 以後我再寫一篇來專門講解。

# 登入 GCP CLI
gcloud auth login

# 設定電腦預設專案 Token
gcloud auth application-default login --project xxxxx

# 初始化
terraform init

# 部屬雲端資源到 GCP
terraform apply

# 輸出建立好的 Service Acoount Credential
terraform output google_service_account_key

Velero 安裝

Velero Docs - Basic Install

參考上面官方文件,要安裝 Velero 有兩個部份,首先先安裝 CLI 用來操作集群的備份、還原以及看 Log 等操作。

helm-charts/charts/velero at main · vmware-tanzu/helm-charts
Contains Helm charts for Kubernetes related open source tools - vmware-tanzu/helm-charts

另一部份則是 Server 端的組件,指的是 Velero 裝在你的集群中的部份,負責接收 CLI 的命令並打包集群中的資源以及 PV 的資料上傳到你指定的 Object Storage 中。

具體能參考上面這個官方的 Helm Chart 做安裝,安裝方法我這裡是使用 Kustomize 來同時安裝我的 Chart 以及管理我的 GCP 憑證。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: velero
helmCharts:
- repo: https://vmware-tanzu.github.io/helm-charts
  name: velero
  version: 5.0.1
  includeCRDs: true
  namespace: velero
  releaseName: velero
  valuesFile: ./values.yaml
secretGenerator:
- name: gcp-cred
  options:
    disableNameSuffixHash: true
  files:
  - ./configs/credential.json

上面是寫好的 kustomize 檔案,新建一個資料夾,然後儲存為 kustomization.yaml 就能使用,上一個步驟 Terrafrom 產生的 credential 除儲存在資料夾內 ./configs/credential.json 位置。

而 ./values.yaml  檔案的內容則複製這個連結的內容就好。然後修改以下幾個地方:

initContainers 設定安裝 GCP Plugin
configuration 設定 GCP Provider
configuration.defaultVolumesToFsBackup 設為 true 自動備份所有 Pod 的 Volume
nodeAgent 設為 true 部屬能備份非雲廠商的 PV
最後按須創建你的定時備份設定,像這裡我是每天半夜 4 點備份 ghost, n8n, plex 這三個 Namespace 的所有資料到 GCS 上。

useOwnerReferencesInBackup 一定不要設成 true 不然不同集群會不能同步備份。

更新好 ./values.yaml 之後就只要用下面的指令安裝一下就可以了:

kubectl create ns velero
kustomize build --enable-helm | kubectl apply -n velero -

指令操作

在安裝完成之後你可以再電腦上下這個指令,看到你的定期備份。

而我這邊是已經安裝完跑了大概一個禮拜,可以下這樣的指令來看雲端上有多少的備份。

創建備份

接著我們來試一下手動創建一個備份,可以用如下的指令操作。

等一段時間後,備份狀態變成 Completed 我們就自己來當手賤人,刪掉備份的 Namespace。

原地還原

接著用這個指令從剛剛串建好的備份還原。

一段時間後等待備份完成,就可以去檢查一下你的 Namespace 裡的應用程式都有成功還原而且資料也都正確復原,注意這個是一個包含 MySQL 資料庫並且有掛 PV 都是能夠正常備份還原的。

集群遷移到 GCP

建立集群

關於如何用 Terraform 在 GCP 上建立 GKE 集群日後有機會會在另外寫文章詳細介紹,下方有寫好的 Terraform 檔案大家可以直接拿去用。

下載後之後進入資料夾,執行以下指令就可以,大概會需要 5 分鐘來建立集群。

# 初始化
terraform init

# 部屬雲端資源到 GCP
terraform apply

# 取得 GKE kubeconfig
gcloud container clusters get-credentials cluster-name --region="asia-east1"

安裝 Velero

主要細節參考這份官方文件

Velero Docs - Cluster migration

接著我們依照一開始安裝的方式來安裝,不過在安裝之前有幾個設定要調整。

configuration.backupStorageLocation[*].accessMode 要改成 ReadOnly 避免誤刪 GCS 上的資料
設定原始集群跟 GKE 裡的 StorageClass 的映射,具體參考下面的文章,讓 Velero 幫忙把原始的集群備份的 PVC StorageClass 從 longhorn 自動換成 GKE 上的 standard-rwx。
Velero Docs - Restore Reference
kubectl apply -f - << EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: change-storage-class
  namespace: velero
  labels:
    velero.io/plugin-config: ""
    velero.io/change-storage-class: RestoreItemAction
data:
  longhorn: standard
EOF

還原

檢查原始集群上的備份有同步到新集群,接著從備份創建一個還原。

等到看到備份的狀態是 Completed 就完成了。

最後

有了 Velero 我們可以很方便的備份還原自己的集群,並在發生意外時隨時把集群還原,甚至能還原到不同的雲端環境中,我自己使用的心得是,除了不同雲環境下要稍微去看一下 StorageClass 的支援程度 (RWO, RWX) 要記得去啟用之外,其他部份使用起來都算是很方便。