はじめに
VeleroはKubernetes環境のバックアップを取得するために利用しています。
MinioはAWS S3互換のObject Storageです。
Veleroをインストールする手順は、Harborの記事に書いていたのですが、バージョンアップするタイミングで独立した記事にまとめました。
namespace全体をバックアップできるので、アプリケーションをnamespaceで分離している場合にはとても便利です。
参考資料
- https://qiita.com/YasuhiroABE/items/8d247a3abbcf484e1c65 - Velero+MinioによるHarborの引越し作業
- https://goharbor.io/docs/main/administration/backup-restore/ - Harbor 公式ガイド
- https://github.com/vmware-tanzu/velero-plugin-for-aws - Github Velero AWSプラグイン
環境
新規にインストールしたのは次のような環境です。
- Kubernetes v1.25.6 (Kubespray v2.21.0) → v1.27.5 (Kubespray v2.23.0) → v1.29.5 (Kubespray v2.25.0)
- Rook/Ceph v1.9.13 (Ceph v16.2.6) → v1.14.5 (Ceph v18.2.2)
- Velero v1.10.3 → 1.11.1 → 1.12.0-rc.1 → v1.12.2 → v1.14.0
- velero-plugin-for-aws v1.6.2 → v1.7.1 → v1.8.0-rc.1 → v1.8.2 → v1.10.0
- Minio (RELEASE.2023-07-07T07-13-57Z) → (Helm 5.2.0, RELEASE.2024-03-03T17-50-39Z)
- mc (RELEASE.2023-07-07T05-25-51Z) → (RELEASE.2024-05-24T09-08-49Z)
ここではオンプレミスで導入したKubernetesとRook/CephによるPVを基盤として利用しています。
AmazonのEKS+S3やGoogleのGKE+Cloud Volumesを利用する場合にはsnapshotを積極的に使うことになると思うので、ここでのVeleroの導入手順は参考にしないでください。
準備作業
- veleroコマンドを/usr/local/sbin/veleroに実行権限を付けて配置 (permisison: 0755)
- credentials-velero ファイルを配置
credentials-velero ファイルのフォーマット
Minioで作成したbucketにアクセス権を持つID,Passwordを次のような形式でファイルをあらかじめ作成しておきます。
[default]
aws_access_key_id = ed573f5ea128ca21
aws_secret_access_key = c7c443a8fa8404abfcaab6fe09922c8f
インストール手順
次のようなMakefileを作成しています。
v1.14.0をインストールする際に利用したMakefileの内容で置き換えました。kopiaを使うように変更しています。
.PHONY: all
all:
@echo reference - https://github.com/vmware-tanzu/velero-plugin-for-aws
.PHONY: install
install:
sudo velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.10.0 \
--bucket my-backup-bucket \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--uploader-type kopia \
--use-node-agent \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://my-minio-svc.minio.svc.cluster.local:9000
.PHONY: delete
delete:
@echo sudo velero uninstall
インストール自体は、makeコマンドを利用して実施しています。
$ make install
動作確認には、veleroのPodのログを確認します。
v1.14.0のドキュメントではbackup-location
を別に作成する手順になっていますが、--backup-location-config ...
で指示を与えると自動的に作成してくれます。
$ sudo velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero-bucket Available 2024-06-21 01:49:45 +0000 UTC ReadWrite true
Veleroによるバックアップの取得
テスト用のnamespaceを作成し、いくつかPod, PVCを配置して、バックアップが動作するか検証します。
Namespack, pod と pvc の作成
まずnamespace velero-test を作成します。
$ sudo kubectl create ns velero-test
次にテスト用のPod, PVCを作成するYAMLファイルを準備します。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: rook-ceph-block
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-file-pvc
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: rook-cephfs
resources:
requests:
storage: 1Gi
これらのPVCを利用するnginxをdeployします。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-block-storage
spec:
replicas: 1
selector:
matchLabels:
app: nginx-block-storage
template:
metadata:
labels:
app: nginx-block-storage
annotations:
backup.velero.io/backup-volumes: nginx-data-storage
spec:
containers:
- name: nginx-block-storage
image: nginx:latest
imagePullPolicy: "Always"
ports:
- containerPort: 80
volumeMounts:
- name: nginx-data-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-data-storage
persistentVolumeClaim:
claimName: nginx-block-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-file-storage
spec:
replicas: 2
selector:
matchLabels:
app: nginx-file-storage
template:
metadata:
labels:
app: nginx-file-storage
annotations:
backup.velero.io/backup-volumes: nginx-data-storage
spec:
containers:
- name: nginx-file-storage
image: nginx:latest
imagePullPolicy: "Always"
ports:
- containerPort: 80
volumeMounts:
- name: nginx-data-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-data-storage
persistentVolumeClaim:
claimName: nginx-file-pvc
アクセスするためのServiceオブジェクトを作成します。
---
apiVersion: v1
kind: Service
metadata:
name: nginx-block-storage
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-block-storage
---
apiVersion: v1
kind: Service
metadata:
name: nginx-file-storage
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-file-storage
これらのYAMLファイルを反映し、nginxを動作させます。
$ alias kubectl="sudo kubectl -n velero-test"
$ sudo kubectl apply -f 01.pvc.yaml -f 02.deploy.yaml -f 03.svc.yaml
バックアップが機能しているか確認するために、適当なコンテンツを配置します。
$ kubectl exec -it "$(kubectl get pod -l app=nginx-block-storage -o jsonpath={.items[0].metadata.name})" -- bash -c "echo Hello Block Nginx, $(id -un) at $(date) > /usr/share/nginx/html/index.html"
$ kubectl exec -it "$(kubectl get pod -l app=nginx-file-storage -o jsonpath={.items[0].metadata.name})" -- bash -c "echo Hello Filesystem Nginx, $(id -un) at $(date) > /usr/share/nginx/html/index.html"
配置されたindex.htmlの内容はLoadBalancerに割り当てられたIPを通すか、ClusterIPで動作していればnginxのPodにexecコマンドで入ってcurlコマンド経由で確認できます。
配置したindex.htmlはシンプルな内容を返します。
$ curl 192.168.100.192
Hello Block Nginx, ubuntu at Sun Sep 10 09:09:44 AM UTC 2023
$ curl 192.168.100.193
Hello Filesystem Nginx, ubuntu at Sun Sep 10 09:09:52 AM UTC 2023
Backupの取得
バックアップは次のように実行しています。
## YAMLファイルにannotationを追加したのでコメントアウト
# $ sudo kubectl -n velero-test annotate pod/nginx-block-storage-85bd475f8b-fnjf5 backup.velero.io/backup-volumes=nginx-data-storage
# $ sudo kubectl -n velero-test annotate pod/nginx-file-storage-54cd65d46c-qk8fk backup.velero.io/backup-volumes=nginx-data-storage
## namespaceを指定して
$ sudo velero backup create velero-test-$(date +%Y%m%d.%H%M%S) --include-namespaces velero-test --wait
正常なレポートを出力させるための/etc/hostsの変更
backup describeでの出力は一見正常にみえますが、--detailsオプションを指定するとResource List:の取得に失敗しています。
Resource List: <error getting backup resource list: Get "http://my-minio-svc.minio.svc.cluster.local:9000/my-backup-bucket/backups/velero-test-20230910.1845/velero-test-20230910.1845-resource-list.json.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=8b81073d6343afcc%2F20230910%2Fminio%2Fs3%2Faws4_request&X-Amz-Date=20230910T094928Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=31aa96c9cd32e364250aa3f3866bd9fb5ae8a772f6d962417b31810de30fdfc8": dial tcp: lookup my-minio-svc.minio.svc.cluster.local on 127.0.0.53:53: server misbehaving>
backup logsコマンドはファイルの取得でエラーになっています。
An error occurred: Get "http://my-minio-svc.minio.svc.cluster.local:9000/my-backup-bucket/backups/velero-test-20230910.2043/velero-test-20230910.2043-logs.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=8b81073d6343afcc%2F20230910%2Fminio%2Fs3%2Faws4_request&X-Amz-Date=20230910T114625Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=d91e85847e64ec4ef3313e858c6ecff25576d51337fabe06fce2242c5e9aea3b": dial tcp: lookup my-minio-svc.minio.svc.cluster.local on 127.0.0.53:53: server misbehaving
これはveleroを実行している環境からmy-minio-svc.minio.svc.cluster.localに対応するIPアドレスが取得できない事が原因です。
MinioにServiceオブジェクトを追加してLANのIPからアクセスできるようにした後、/etc/hostsにmy-minio-svc.minio.svc.cluster.localに対応するIPアドレスを追加することで正常な出力を得ることができます。
---
apiVersion: v1
kind: Service
metadata:
name: my-minio-lb-svc
namespace: minio
spec:
ports:
- name: http
port: 9000
protocol: TCP
targetPort: 9000
selector:
app: minio
release: my-minio
type: LoadBalancer
loadBalancerIP: 192.168.100.159
/etc/hostsにLANからアクセスできるIPアドレスとmy-minio-svc.minio.svc.cluster.localとの対応を追加します。
192.168.100.159 my-minio-svc.minio.svc.cluster.local
この状態でdescribeコマンドを入力すると正しい内容が出力されます。
$ sudo velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
velero-test-20240122.024922 Completed 0 0 2024-01-22 02:52:29 +0000 UTC 29d default <none>
$ sudo velero backup describe velero-test-20240122.024922 --details
Name: velero-test-20240122.024922
Namespace: velero
Labels: velero.io/storage-location=default
Annotations: velero.io/resource-timeout=10m0s
velero.io/source-cluster-k8s-gitversion=v1.27.7
velero.io/source-cluster-k8s-major-version=1
velero.io/source-cluster-k8s-minor-version=27
Phase: Completed
...
Resource List:
apps/v1/Deployment:
- velero-test/nginx-block-storage
- velero-test/nginx-file-storage
apps/v1/ReplicaSet:
- velero-test/nginx-block-storage-856b466974
- velero-test/nginx-file-storage-77ff568999
discovery.k8s.io/v1/EndpointSlice:
- velero-test/nginx-block-storage-kxrt8
- velero-test/nginx-file-storage-gs5mx
v1/ConfigMap:
- velero-test/kube-root-ca.crt
v1/Endpoints:
- velero-test/nginx-block-storage
- velero-test/nginx-file-storage
...
v1/Service:
- velero-test/nginx-block-storage
- velero-test/nginx-file-storage
v1/ServiceAccount:
- velero-test/default
Velero-Native Snapshots: <none included>
kopia Backups:
Completed:
velero-test/nginx-block-storage-856b466974-cwp75: nginx-data-storage
velero-test/nginx-file-storage-77ff568999-8pl49: nginx-data-storage
sudo velero logs
についても正常に出力されるようになりました。
リストアの実行
namespaceを削除して同名のnamespaceにリストアする方法もありますが、ここでは別のnamespaceを指定してrestoreしていきます。
$ sudo velero restore create --from-backup velero-test-20230910.1835 --namespace-mappings velero-test:velero-test2 --wait
curlを使ってサービスにアクセスすると、PVC上にあるindex.htmlが無事に復元されていることが分かりました。
$ sudo kubectl -n velero-test2 get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-block-storage LoadBalancer 10.233.14.151 192.168.100.194 80:32494/TCP 4m29s
nginx-file-storage LoadBalancer 10.233.16.125 192.168.100.195 80:30019/TCP 4m29s
$ curl 192.168.100.194
Hello Block Nginx, ubuntu at Sun Sep 10 09:09:44 AM UTC 2023
$ curl 192.168.100.195
Hello Filesystem Nginx, ubuntu at Sun Sep 10 09:09:52 AM UTC 2023
さいごに
Veleroは変更作業時に利用しているので、都度 delete & install を実施して問題ない状態です。
とはいえ正常に動作するか確認は必要なので、簡単なテスト用のプロジェクトを作成できるようにメモを残しました。
これを利用して他のクラスターでもveleroを準備していく予定です。
以上