Kubernetes 集羣備份是一大難點。雖然能夠經過etcd來進行備份來實現K8S集羣備份,可是這種備份很難恢復單個 Namespace
。html
對於K8s集羣數據的備份和恢復,以及複製當前集羣數據到其餘集羣等都很是方便。能夠在兩個集羣間克隆應用和命名空間,來建立一個臨時性的開發環境。linux
Velero 是一個雲原生的災難恢復和遷移工具,它自己也是開源的, 採用 Go 語言編寫,能夠安全的備份、恢復和遷移Kubernetes集羣資源和持久卷。nginx
Velero 是西班牙語,意思是帆船,很是符合 Kubernetes 社區的命名風格。Velero 的開發公司 Heptio,以前已被 VMware 收購,其創始人2014就任於Google,當時被認爲是 Kubernetes 核心成員。git
Velero 是一種雲原生的Kubernetes優化方法,支持標準的K8S集羣,既能夠是私有云平臺也能夠是公有云。除了災備以外它還能作資源移轉,支持把容器應用從一個集羣遷移到另外一個集羣。github
Heptio Velero ( 之前的名字爲 ARK) 是一款用於 Kubernetes 集羣資源和持久存儲卷(PV)的備份、遷移以及災難恢復等的開源工具。web
使用velero能夠對集羣進行備份和恢復,下降集羣DR形成的影響。velero的基本原理就是將集羣的數據備份到對象存儲中,在恢復的時候將數據從對象存儲中拉取下來。能夠從官方文檔查看可接收的對象存儲,本地存儲可使用Minio。下面演示使用velero將openstack上的openshift集羣備份恢復到阿里雲的openshift上。shell
Velero
客戶端發送備份指令。Kubernetes
集羣內就會建立一個 Backup
對象。BackupController
監測 Backup
對象並開始備份過程。BackupController
會向 API Server
查詢相關數據。BackupController
將查詢到的數據備份到遠端的對象存儲。Velero
目前包含如下特性:編程
Kubernetes
集羣數據備份和恢復Kubernetes
集羣的資源到其它 Kubernetes
集羣Velero
組件一共分兩部分,分別是服務端和客戶端。json
Kubernetes
的集羣中kubectl
及集羣 kubeconfig
的機器上災備場景
:提供備份恢復k8s集羣的能力遷移場景
:提供拷貝集羣資源到其餘集羣的能力(複製同步開發,測試,生產環境的集羣配置,簡化環境配置)與 Etcd 備份相比,直接備份 Etcd
是將集羣的所有資源備份起來。而 Velero
就是能夠對 Kubernetes
集羣內對象級別進行備份。除了對 Kubernetes
集羣進行總體備份外,Velero
還能夠經過對 Type
、Namespace
、Label
等對象進行分類備份或者恢復。
注意: 備份過程當中建立的對象是不會被備份的。
Velero
在 Kubernetes
集羣中建立了不少 CRD
以及相關的控制器,進行備份恢復等操做實質上是對相關 CRD
的操做。
# Velero 在 Kubernetes 集羣中建立的 CRD $ kubectl -n velero get crds -l component=velero NAME CREATED AT backups.velero.io 2019-08-28T03:19:56Z backupstoragelocations.velero.io 2019-08-28T03:19:56Z deletebackuprequests.velero.io 2019-08-28T03:19:56Z downloadrequests.velero.io 2019-08-28T03:19:56Z podvolumebackups.velero.io 2019-08-28T03:19:56Z podvolumerestores.velero.io 2019-08-28T03:19:56Z resticrepositories.velero.io 2019-08-28T03:19:56Z restores.velero.io 2019-08-28T03:19:56Z schedules.velero.io 2019-08-28T03:19:56Z serverstatusrequests.velero.io 2019-08-28T03:19:56Z volumesnapshotlocations.velero.io 2019-08-28T03:19:56Z
對象存儲的數據是惟一的數據源,也就是說 Kubernetes
集羣內的控制器會檢查遠程的 OSS
存儲,發現有備份就會在集羣內建立相關 CRD
。若是發現遠端存儲沒有當前集羣內的 CRD
所關聯的存儲數據,那麼就會刪除當前集羣內的 CRD
。
Velero
支持兩種關於後端存儲的 CRD
,分別是 BackupStorageLocation
和 VolumeSnapshotLocation
。
BackupStorageLocation
主要用來定義 Kubernetes
集羣資源的數據存放位置,也就是集羣對象數據,不是 PVC
的數據。主要支持的後端存儲是 S3
兼容的存儲,好比:Mino
和阿里雲 OSS
等。
apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: name: default namespace: velero spec: # 只有 aws gcp azure provider: aws # 存儲主要配置 objectStorage: # bucket 的名稱 bucket: myBucket # bucket內的 prefix: backup # 不一樣的 provider 不一樣的配置 config: #bucket地區 region: us-west-2 # s3認證信息 profile: "default" # 使用 Minio 的時候加上,默認爲 false # AWS 的 S3 能夠支持兩種 Url Bucket URL # 1 Path style URL: http://s3endpoint/BUCKET # 2 Virtual-hosted style URL: http://oss-cn-beijing.s3endpoint 將 Bucker Name 放到了 Host Header中 # 3 阿里雲僅僅支持 Virtual hosted 若是下面寫上 true, 阿里雲 OSS 會報錯 403 s3ForcePathStyle: "false" # s3的地址,格式爲 http://minio:9000 s3Url: http://minio:9000
apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: labels: component: velero name: default namespace: velero spec: config: region: oss-cn-beijing s3Url: http://oss-cn-beijing.aliyuncs.com s3ForcePathStyle: "false" objectStorage: bucket: build-jenkins prefix: "" provider: aws
VolumeSnapshotLocation 主要用來給 PV 作快照,須要雲提供商提供插件。阿里雲已經提供了插件,這個須要使用 CSI 等存儲機制。你也可使用專門的備份工具 Restic
,把 PV 數據備份到阿里雲 OSS 中去(安裝時須要自定義選項)。
# 安裝時須要自定義選項 --use-restic # 這裏咱們存儲 PV 使用的是 OSS 也就是 BackupStorageLocation,所以不用建立 VolumeSnapshotLocation 對象 --use-volume-snapshots=false
Restic 是一款 GO 語言開發的數據加密備份工具,顧名思義,能夠將本地數據加密後傳輸到指定的倉庫。支持的倉庫有 Local、SFTP、Aws S三、Minio、OpenStack Swift、Backblaze B二、Azure BS、Google Cloud storage、Rest Server。
項目地址:https://github.com/restic/restic
wget https://github.com/vmware-tanzu/velero/releases/download/v1.4.2/velero-v1.4.2-linux-amd64.tar.gz tar -zxvf velero-v1.4.2-linux-amd64.tar.gz
cd velero-v1.4.2-linux-amd64 [root@master velero-v1.4.2-linux-amd64]# cat examples/minio/00-minio-deployment.yaml --- apiVersion: v1 kind: Namespace metadata: name: velero --- apiVersion: apps/v1 kind: Deployment metadata: namespace: velero name: minio labels: component: minio spec: strategy: type: Recreate selector: matchLabels: component: minio template: metadata: labels: component: minio spec: volumes: - name: storage emptyDir: {} - name: config emptyDir: {} containers: - name: minio image: minio/minio:latest imagePullPolicy: IfNotPresent args: - server - /storage - --config-dir=/config env: - name: MINIO_ACCESS_KEY value: "minio" - name: MINIO_SECRET_KEY value: "minio123" ports: - containerPort: 9000 volumeMounts: - name: storage mountPath: "/storage" - name: config mountPath: "/config" --- apiVersion: v1 kind: Service metadata: namespace: velero name: minio labels: component: minio spec: # ClusterIP is recommended for production environments. # Change to NodePort if needed per documentation, # but only if you run Minio in a test/trial environment, for example with Minikube. type: ClusterIP ports: - port: 9000 targetPort: 9000 protocol: TCP selector: component: minio --- apiVersion: batch/v1 kind: Job metadata: namespace: velero name: minio-setup labels: component: minio spec: template: metadata: name: minio-setup spec: restartPolicy: OnFailure volumes: - name: config emptyDir: {} containers: - name: mc image: minio/mc:latest imagePullPolicy: IfNotPresent command: - /bin/sh - -c - "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero" volumeMounts: - name: config mountPath: "/config"
由上面資源清淡咱們能夠看到,在安裝minio的時候
MINIO_ACCESS_KEY:minio
MINIO_SECRET_KEY:minio123
service的地址爲:http://minio:9000,類型爲ClusterIP,咱們能夠映射爲NodePort查看
最後執行了一個job來建立一個名稱爲:velero/velero的bucket,在建立的時候適應了。
[root@master velero-v1.4.2-linux-amd64]# kubectl apply -f examples/minio/00-minio-deployment.yaml namespace/velero created deployment.apps/minio created service/minio created job.batch/minio-setup created [root@master velero-v1.4.2-linux-amd64]# kubectl get all -n velero NAME READY STATUS RESTARTS AGE pod/minio-fdd868c5-xv52k 0/1 ContainerCreating 0 14s pod/minio-setup-hktjb 0/1 ContainerCreating 0 14s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/minio ClusterIP 10.233.39.204 <none> 9000/TCP 14s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/minio 0/1 1 0 14s NAME DESIRED CURRENT READY AGE replicaset.apps/minio-fdd868c5 1 1 0 14s NAME COMPLETIONS DURATION AGE job.batch/minio-setup 0/1 14s 14s
待服務都已經啓動完畢,能夠登陸minio查看velero/velero的bucket是否建立成功。
修改svc,登陸查看
[root@master velero-v1.4.2-linux-amd64]# kubectl get svc -n velero minio NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE minio NodePort 10.233.39.204 <none> 9000:30401/TCP 2m26s
安裝velero須要建立能正常登陸minio的密鑰
cat > credentials-velero <<EOF [default] aws_access_key_id = minio aws_secret_access_key = minio123 EOF # 安裝velero cp velero /usr/bin/
# 啓用快速補全 velero completion bash velero install \ --provider aws \ --plugins velero/velero-plugin-for-aws:v1.0.0 \ --bucket velero \ --secret-file ./credentials-velero \ --use-volume-snapshots=false \ --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000 [root@master velero-v1.4.2-linux-amd64]# velero install --provider aws --plugins velero/velero-plugin-for-aws:v1.0.0 --bucket velero --secret-file ./credentials-velero --use-volume-snapshots=false --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000 CustomResourceDefinition/backups.velero.io: attempting to create resource CustomResourceDefinition/backups.velero.io: created CustomResourceDefinition/backupstoragelocations.velero.io: attempting to create resource CustomResourceDefinition/backupstoragelocations.velero.io: created CustomResourceDefinition/deletebackuprequests.velero.io: attempting to create resource CustomResourceDefinition/deletebackuprequests.velero.io: created CustomResourceDefinition/downloadrequests.velero.io: attempting to create resource CustomResourceDefinition/downloadrequests.velero.io: created CustomResourceDefinition/podvolumebackups.velero.io: attempting to create resource CustomResourceDefinition/podvolumebackups.velero.io: created CustomResourceDefinition/podvolumerestores.velero.io: attempting to create resource CustomResourceDefinition/podvolumerestores.velero.io: created CustomResourceDefinition/resticrepositories.velero.io: attempting to create resource CustomResourceDefinition/resticrepositories.velero.io: created CustomResourceDefinition/restores.velero.io: attempting to create resource CustomResourceDefinition/restores.velero.io: created CustomResourceDefinition/schedules.velero.io: attempting to create resource CustomResourceDefinition/schedules.velero.io: created CustomResourceDefinition/serverstatusrequests.velero.io: attempting to create resource CustomResourceDefinition/serverstatusrequests.velero.io: created CustomResourceDefinition/volumesnapshotlocations.velero.io: attempting to create resource CustomResourceDefinition/volumesnapshotlocations.velero.io: created Waiting for resources to be ready in cluster... Namespace/velero: attempting to create resource Namespace/velero: already exists, proceeding Namespace/velero: created ClusterRoleBinding/velero: attempting to create resource ClusterRoleBinding/velero: created ServiceAccount/velero: attempting to create resource ServiceAccount/velero: created Secret/cloud-credentials: attempting to create resource Secret/cloud-credentials: created BackupStorageLocation/default: attempting to create resource BackupStorageLocation/default: created Deployment/velero: attempting to create resource Deployment/velero: created Velero is installed! ⛵ Use 'kubectl logs deployment/velero -n velero' to view the status. [root@master velero-v1.4.2-linux-amd64]# kubectl api-versions |grep velero velero.io/v1 [root@master velero-v1.4.2-linux-amd64]# kubectl get pod -n velero NAME READY STATUS RESTARTS AGE minio-fdd868c5-xv52k 1/1 Running 0 56m minio-setup-hktjb 0/1 Completed 0 56m velero-56fbc5d69c-8v2q7 1/1 Running 0 32m
至此velero就已經所有部署完成。
$ velero create backup NAME [flags] # 剔除 namespace --exclude-namespaces stringArray namespaces to exclude from the backup # 剔除資源類型 --exclude-resources stringArray resources to exclude from the backup, formatted as resource.group, such as storageclasses.storage.k8s.io # 包含集羣資源類型 --include-cluster-resources optionalBool[=true] include cluster-scoped resources in the backup # 包含 namespace --include-namespaces stringArray namespaces to include in the backup (use '*' for all namespaces) (default *) # 包含 namespace 資源類型 --include-resources stringArray resources to include in the backup, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources) # 給這個備份加上標籤 --labels mapStringString labels to apply to the backup -o, --output string Output display format. For create commands, display the object but do not send it to the server. Valid formats are 'table', 'json', and 'yaml'. 'table' is not valid for the install command. # 對指定標籤的資源進行備份 -l, --selector labelSelector only back up resources matching this label selector (default <none>) # 對 PV 建立快照 --snapshot-volumes optionalBool[=true] take snapshots of PersistentVolumes as part of the backup # 指定備份的位置 --storage-location string location in which to store the backup # 備份數據多久刪掉 --ttl duration how long before the backup can be garbage collected (default 720h0m0s) # 指定快照的位置,也就是哪個公有云驅動 --volume-snapshot-locations strings list of locations (at most one per provider) where volume snapshots should be stored
velero很是的人性化,在安裝包中已經爲咱們準備好了測試demo,咱們能夠利用測試demo來進行測試驗證。
[root@master velero-v1.4.2-linux-amd64]# kubectl apply -f examples/nginx-app/base.yaml namespace/nginx-example created deployment.apps/nginx-deployment created service/my-nginx created [root@master velero-v1.4.2-linux-amd64]# kubectl get all -n nginx-example NAME READY STATUS RESTARTS AGE pod/nginx-deployment-f4769bfdf-8jrsz 0/1 ContainerCreating 0 12s pod/nginx-deployment-f4769bfdf-sqfp4 0/1 ContainerCreating 0 12s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-nginx LoadBalancer 10.233.10.49 <pending> 80:32401/TCP 13s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 0/2 2 0 14s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-f4769bfdf 2 2 0 14s
[root@master velero-v1.4.2-linux-amd64]# 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. [root@master velero-v1.4.2-linux-amd64]# velero backup describe nginx-backup Name: nginx-backup Namespace: velero Labels: velero.io/storage-location=default Annotations: velero.io/source-cluster-k8s-gitversion=v1.15.5 velero.io/source-cluster-k8s-major-version=1 velero.io/source-cluster-k8s-minor-version=1 Phase: Completed Errors: 0 Warnings: 0 Namespaces: Included: nginx-example Excluded: <none> Resources: Included: * Excluded: <none> Cluster-scoped: auto Label selector: <none> Storage Location: default Velero-Native Snapshot PVs: auto TTL: 720h0m0s Hooks: <none> Backup Format Version: 1 Started: 2020-07-21 19:12:16 +0800 CST Completed: 2020-07-21 19:12:24 +0800 CST Expiration: 2020-08-20 19:12:16 +0800 CST Total items to be backed up: 23 Items backed up: 23 Velero-Native Snapshots: <none included>
[root@master velero-v1.4.2-linux-amd64]# kubectl delete -f examples/nginx-app/base.yaml namespace "nginx-example" deleted deployment.apps "nginx-deployment" deleted service "my-nginx" deleted
[root@master velero-v1.4.2-linux-amd64]# velero restore create --from-backup nginx-backup --wait Restore request "nginx-backup-20200722134728" submitted successfully. Waiting for restore to complete. You may safely press ctrl-c to stop waiting - your restore will continue in the background. Restore completed with status: Completed. You may check for more information using the commands `velero restore describe nginx-backup-20200722134728` and `velero restore logs nginx-backup-20200722134728`. [root@master velero-v1.4.2-linux-amd64]# kubectl get pods -n nginx-example NAME READY STATUS RESTARTS AGE nginx-deployment-f4769bfdf-8jrsz 1/1 Running 0 7s nginx-deployment-f4769bfdf-sqfp4 1/1 Running 0 7s
注意:velero restore
恢復不會覆蓋已有的資源
,只恢復當前集羣中不存在的資源
。已有的資源不會回滾到以前的版本,如須要回滾,需在restore以前提早刪除現有的資源。
本實例實踐如何在阿里雲容器服務 ACK 使用 Velero 完成備份和遷移。
ACK 插件地址:https://github.com/AliyunContainerService/velero-plugin
因爲爲低頻存儲,類型爲低頻訪問存儲,權限爲私有
在此最好須要建立一個阿里雲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。
git clone https://github.com/AliyunContainerService/velero-plugin
install/credentials-velero
文件,將新建用戶中得到的 AccessKeyID
和 AccessKeySecret
填入。ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
1.建立 velero 命名空間 和 阿里雲 secret
# 建立 velero 命名空間 $ kubectl create namespace velero # 建立阿里雲 secret $ kubectl create secret generic cloud-credentials --namespace velero --from-file cloud=install/credentials-velero
2.替換crd中對象存儲信息,部署crd和velero
# OSS Bucket 名稱 $ BUCKET=devops-k8s-backup # OSS 所在可用區 $ REGION=cn-shanghai # bucket 名字 $ prefix=velero # 部署 velero CRD $ kubectl apply -f install/00-crds.yaml # 替換 OSS Bucket 與 OSS 所在可用區 $ sed -i "s#<BUCKET>#$BUCKET#" install/01-velero.yaml $ sed -i "s#<REGION>#$REGION#" install/01-velero.yaml # 替換bucket 中名字prifix # 查看差別 [root@master velero-plugin]# git diff install/01-velero.yaml diff --git a/install/01-velero.yaml b/install/01-velero.yaml index 5669860..7dd4c5a 100644 --- a/install/01-velero.yaml +++ b/install/01-velero.yaml @@ -31,10 +31,10 @@ metadata: namespace: velero spec: config: - region: <REGION> + region: cn-shanghai objectStorage: - bucket: <BUCKET> - prefix: "" + bucket: devops-k8s-backup + prefix: "velero" provider: alibabacloud --- @@ -47,7 +47,7 @@ metadata: namespace: velero spec: config: - region: <REGION> + region: cn-shanghai provider: alibabacloud --- # 建立認證secret kubectl create namespace velero # 部署velero $ kubectl apply -f install/ # 查看velero $ kubectl get pods -n velero [root@master velero-plugin]# kubectl get pods -n velero NAME READY STATUS RESTARTS AGE velero-fcc8d77b8-569jz 1/1 Running 0 45s # 查看位置 [root@master velero-plugin]# velero get backup-locations NAME PROVIDER BUCKET/PREFIX ACCESS MODE default alibabacloud devops-k8s-backup/velero ReadWrite
$ velero backup create nginx-example --include-namespaces nginx-example
velero restore create --from-backup nginx-example
# Create a backup every 6 hours velero create schedule NAME --schedule="0 */6 * * *" # Create a backup every 6 hours with the @every notation velero create schedule NAME --schedule="@every 6h" # Create a daily backup of the web namespace velero create schedule NAME --schedule="@every 24h" --include-namespaces web # Create a weekly backup, each living for 90 days (2160 hours) velero create schedule NAME --schedule="@every 168h" --ttl 2160h0m0s # 每日對anchnet-devops-dev/anchnet-devops-test/anchnet-devops-prod/xxxxx-devops-common-test 名稱空間進行備份 velero create schedule anchnet-devops-dev --schedule="@every 24h" --include-namespaces xxxxx-devops-dev velero create schedule anchnet-devops-test --schedule="@every 24h" --include-namespaces xxxxx-devops-test velero create schedule anchnet-devops-prod --schedule="@every 24h" --include-namespaces xxxxx-devops-prod velero create schedule anchnet-devops-common-test --schedule="@every 24h" --include-namespaces xxxxx-devops-common-test
velero restore
恢復不會覆蓋已有的資源
,只恢復當前集羣中不存在的資源
。已有的資源不會回滾到以前的版本,如須要回滾,需在restore以前提早刪除現有的資源。後期能夠講velero做爲一個crontjob來運行,按期備份數據。
error: unable to recognize "filebeat.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
,將yml配置文件內的api接口修改成 apps/v1 ,致使緣由爲之間使用的kubernetes 版本是1.14.x版本,1.16.x 版本放棄部分API支持!