Velero+MinIOのKubernetesリソースバックアップ

リストアうまくいかなかったので未完成ですが、一旦メモ書き。
⇒emptyDirならリストアできた。

環境について

Rancher 2.8.0 on k3s で構築したRKE1クラスタで試しました。
構築方法はラズパイにk3sでRancher構築 とか Rancherでラズパイk8sクラスタ構築 を見ていただければと思います。

NAME   STATUS   ROLES               AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s1   Ready    controlplane,etcd   7d1h   v1.27.8   192.168.0.51   <none>        Ubuntu 22.04.3 LTS   5.15.0-1044-raspi   docker://20.10.24
k8s2   Ready    worker              7d1h   v1.27.8   192.168.0.52   <none>        Ubuntu 22.04.3 LTS   5.15.0-1044-raspi   docker://20.10.24
k8s3   Ready    worker              7d1h   v1.27.8   192.168.0.53   <none>        Ubuntu 22.04.3 LTS   5.15.0-1044-raspi   docker://20.10.24

MinIOもKubernetesで構築したかったけどスペック足りなかったので
別のVMにdocker-composeで構築しました。

MinIO構築

VMはこんな感じで構築。

Ubuntu 20.04.6 LTS  
Client: Docker Engine - Community  
 Version:           25.0.0  
Server: Docker Engine - Community  
 Engine:  
  Version:          25.0.0  
Docker Compose version v2.24.1

docker-compose.ymlはこんな感じにしました。
こちら を参考にさせていただきました。

version: "3"
services:
  minio:
    image: minio/minio:latest
    ports:
      - 9000:9000
      - 9001:9001
    volumes:
      - ./.data/minio/data:/export
      - ./.data/minio/config:/root/.minio
    environment:
      MINIO_ACCESS_KEY: minio
      MINIO_SECRET_KEY: minio123
    command: server /export --console-address ":9001"
# docker compose up -d
[+] Running 1/2
 ⠸ Network root_default    Created                                                                                                                       0.3s 
 ✔ Container root-minio-1  Started                                                                                                                       0.3s 

VMのIPにポート番号9001でアクセスすればコンソールログイン画面が出ると思います。
docker-compose.ymlで指定したユーザー名とパスワードでログインできます。

velero_minio_01.png

veleroと言う名前でバケットを作成しました。

velero_minio_02.png

試しにブラウザからファイルをアップロードします。
良さそうですね。
これでveleroがバックアップ先に使うオブジェクトストレージが完成です。

velero_minio_03.png

Veleroをhelmでインストール

rancherを使います。
veleroと動作確認にcontainer registryを使おうと思うので、
vmware-tanzuphntom のチャートを追加しました。

velero_minio_04.png

先にnamespaceを作成しておきます。

# kubectl create ns velero
namespace/velero created
# kubectl create ns registry
namespace/registry created

作成したnamespaceを指定します。
チャートバージョンは現状最新の5.2.2にしました。

velero_minio_05.png

values.yamlの差分を貼っておきます。
こちら を参考にさせていただきました。
s3urlなどは自身の環境に書き換えてください。

velero_minio_06.png
velero_minio_07.png
velero_minio_08.png

無事デプロイできたようです。
BackupStorageLocationもAvailableなのでMinIOに接続できているようです。

# kubectl get pod -n velero
NAME                                   READY   STATUS    RESTARTS   AGE
node-agent-cfk4k                       1/1     Running   0          36s
node-agent-wvqc9                       1/1     Running   0          36s
velero-5-1705837924-6d57cdfdd6-nz5cb   1/1     Running   0          36s
# kubectl get bsl -n velero
NAME      PHASE       LAST VALIDATED   AGE   DEFAULT
default   Available   25s              40s   true

private container registryをhelmで構築

contaier registryにプッシュしたイメージが
復元できるか試してみようと思ったのでサクッと構築します。
せっかくなのでlocal-path-provisioner で 作成されたPVのバックアップを試してみます。

local-path-provisionerをインストールします。

# kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.26/deploy/local-path-storage.yaml
# kubectl create -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pvc/pvc.yaml
# kubectl create -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pod/pod.yaml

良さそうです。

# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
persistentvolume/pvc-5730d3dd-74da-4ac2-927a-23f3d65ddd51   128Mi      RWO            Delete           Bound    default/local-path-pvc   local-path              50s

NAME                                   STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/local-path-pvc   Bound    pvc-5730d3dd-74da-4ac2-927a-23f3d65ddd51   128Mi      RWO            local-path     62s

先ほど追加したhelmチャートでインストールします。

velero_minio_09.png

差分はこんな感じ。

velero_minio_10.png

無事作成されました。

# kubectl get pod,ingress,pvc -n registry
NAME                                                READY   STATUS    RESTARTS   AGE
pod/docker-registry-1-1705843530-86b8c466f8-7n4cc   1/1     Running   0          29s

NAME                                                     CLASS   HOSTS                          ADDRESS                     PORTS   AGE
ingress.networking.k8s.io/docker-registry-1-1705843530   nginx   registry.tsuchinokometal.com   192.168.0.52,192.168.0.53   80      29s

NAME                                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/docker-registry-1-1705843530   Bound    pvc-48563bd6-4add-4937-a94c-eb10e5d94d46   10Gi       RWO            local-path     29s

適当にDockerfileを準備してイメージをプッシュしてみます。
/etc/docker/daemon.jsonにinsecure-registriesを追加したり、
hostsで名前解決できるようにしておいてください。

# cat /etc/docker/daemon.json
{
 "insecure-registries": ["registry.tsuchinokometal.com"]
}
# cat Dockerfile 
FROM nginx:latest

ENV TZ Asia/Tokyo
RUN echo "${TZ}" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata

# docker build -t registry.tsuchinokometal.com/nginx:latest .

# curl -X GET http://registry.tsuchinokometal.com/v2/_catalog
{"repositories":[]}

# docker push registry.tsuchinokometal.com/nginx:latest

# curl -X GET http://registry.tsuchinokometal.com/v2/_catalog
{"repositories":["nginx"]}

ちゃんとワーカーノードにデータがありました。

# ls /opt/local-path-provisioner/pvc-48563bd6-4add-4937-a94c-eb10e5d94d46_registry_docker-registry-1-1705843530/docker/registry/v2/repositories/
nginx

veleroバックアップ

本題のveleroバックアップとリストアを試します。
まずCLIをインストールします。

# wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.3/velero-v1.12.3-linux-arm64.tar.gz
# tar zxvf velero-v1.12.3-linux-arm64.tar.gz
# mv velero-v1.12.3-linux-arm64/velero /usr/local/bin/
# velero version
Client:
	Version: v1.12.3
	Git commit: 684f71306e9c2fda204a16cb012dc209523cfae1
Server:
	Version: v1.12.3

registryのnamespaceをバックアップしてみます。

# velero backup create registry-backup --include-namespaces registry
Backup request "registry-backup" submitted successfully.
Run `velero backup describe registry-backup` or `velero backup logs registry-backup` for more details.
# velero get backup
NAME              STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
registry-backup   Completed   0        1          2024-01-21 13:43:51 +0000 UTC   29d       default            <none>
# velero describe backup registry-backup
Name:         registry-backup
Namespace:    velero
Labels:       velero.io/storage-location=default
Annotations:  velero.io/resource-timeout=10m0s
              velero.io/source-cluster-k8s-gitversion=v1.27.8
              velero.io/source-cluster-k8s-major-version=1
              velero.io/source-cluster-k8s-minor-version=27

Phase:  Completed


Warnings:
  Velero:     <none>
  Cluster:   resource: /persistentvolumes name: /pvc-48563bd6-4add-4937-a94c-eb10e5d94d46
  Namespaces: <none>

Namespaces:
  Included:  registry
  Excluded:  <none>

Resources:
  Included:        *
  Excluded:        <none>
  Cluster-scoped:  auto

Label selector:  <none>

Or label selector:  <none>

Storage Location:  default

Velero-Native Snapshot PVs:  auto
Snapshot Move Data:          false
Data Mover:                  velero

TTL:  720h0m0s

CSISnapshotTimeout:    10m0s
ItemOperationTimeout:  4h0m0s

Hooks:  <none>

Backup Format Version:  1.1.0

Started:    2024-01-21 13:43:51 +0000 UTC
Completed:  2024-01-21 13:43:55 +0000 UTC

Expiration:  2024-02-20 13:43:51 +0000 UTC

Total items to be backed up:  51
Items backed up:              51

Velero-Native Snapshots: <none included>

Completedだし成功しているようですね。
コンソール上はこんな感じ。

velero_minio_11.png

veleroリストア

RancherGUIでregistryを削除します。

velero_minio_12.png

namespaceも削除します。

# kubectl delete ns registry
namespace "registry" deleted

リストアを実行します。

# velero create restore --from-backup registry-backup
Restore request "registry-backup-20240121135405" submitted successfully.
Run `velero restore describe registry-backup-20240121135405` or `velero restore logs registry-backup-20240121135405` for more details.
# velero get restore
NAME                             BACKUP            STATUS      STARTED                         COMPLETED                       ERRORS   WARNINGS   CREATED                         SELECTOR
registry-backup-20240121135405   registry-backup   Completed   2024-01-21 13:54:05 +0000 UTC   2024-01-21 13:54:15 +0000 UTC   0        4          2024-01-21 13:54:05 +0000 UTC   <none>

Completed!
無事namespaceごとリストアされているようです。

# kubectl get pod,ingress,pvc -n registry
NAME                                                READY   STATUS    RESTARTS   AGE
pod/docker-registry-1-1705843530-86b8c466f8-7n4cc   1/1     Running   0          88s

NAME                                                     CLASS   HOSTS                          ADDRESS                     PORTS   AGE
ingress.networking.k8s.io/docker-registry-1-1705843530   nginx   registry.tsuchinokometal.com   192.168.0.52,192.168.0.53   80      87s

NAME                                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/docker-registry-1-1705843530   Bound    pvc-a9cdf66d-bc12-4a73-a091-d5bb4b2a96ba   10Gi       RWO            local-path     89s

PVのデータが復旧しているか試します。

# curl -X GET http://registry.tsuchinokometal.com/v2/_catalog
{"repositories":[]}

悲しみ
調べてみたらどうやら veleroはhostpathをサポートしていない ようです。
ただ、ドキュメント を見るとlocal volume typeはサポートしているようです。

NOTE: hostPath volumes are not supported, but the local volume type is supported.

emptyDirのバックアップ&リストア

QiitaRestic を使うと emptyDirやNFSのバックアップが取れるという情報があったので
helmで有効化する方法を探したのですが、

deployRestic: true

では有効化できませんでした。
ここのNOTE に書いてあるようになくなったようですね。

では今回インストールしたv1.12で使うにはどうするかというと
こちらのドキュメント にありました。
どうやらノードエージェントをインストールして、
default-volumes-to-fs-backupフラグをつけてバックアップを実行するようです。
今回は常にフラグを有効化するためにhelmで以下の設定にしました。

defaultVolumesToFsBackup: true

では試します。
registryのpersistence.enabledをtrueにして、
デプロイされたdeploymentをeditしてdata volumeをemptyDirに書き換えます。

Volumes:
  data:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)

イメージをプッシュします。

# docker push registry.tsuchinokometal.com/nginx:latest
# curl -X GET http://registry.tsuchinokometal.com/v2/_catalog
{"repositories":["nginx"]}

ワーカーノードにファイルがあることを確認しました。

# ll /var/lib/kubelet/pods/3e719635-d665-45b1-811c-d67182bb5415/volumes/kubernetes.io~empty-dir/data/docker/registry/v2/repositories/
total 12
drwxr-sr-x 3 ubuntu ubuntu 4096 Jan 22 10:18 ./
drwxr-sr-x 4 ubuntu ubuntu 4096 Jan 22 10:18 ../
drwxr-sr-x 5 ubuntu ubuntu 4096 Jan 22 10:18 nginx/

バックアップします。処理時間がちょっと長くなりました。

# velero backup create registry-backup2 --include-namespaces registry
Backup request "registry-backup2" submitted successfully.
Run `velero backup describe registry-backup2` or `velero backup logs registry-backup2` for more details.
# velero get backup
NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
registry-backup    Completed   0        1          2024-01-21 13:43:51 +0000 UTC   29d       default            <none>
registry-backup2   Completed   0        0          2024-01-22 13:27:33 +0000 UTC   29d       default            <none>

namespaceごと削除してリストアします。

# kubectl delete ns registry
namespace "registry" deleted
# velero create restore --from-backup registry-backup2
Restore request "registry-backup2-20240122132846" submitted successfully.
Run `velero restore describe registry-backup2-20240122132846` or `velero restore logs registry-backup2-20240122132846` for more details.
# velero get restore
NAME                              BACKUP             STATUS      STARTED                         COMPLETED                       ERRORS   WARNINGS   CREATED                         SELECTOR
registry-backup-20240121135405    registry-backup    Completed   2024-01-21 13:54:05 +0000 UTC   2024-01-21 13:54:15 +0000 UTC   0        4          2024-01-21 13:54:05 +0000 UTC   <none>
registry-backup2-20240122132846   registry-backup2   Completed   2024-01-22 13:28:46 +0000 UTC   2024-01-22 13:29:09 +0000 UTC   0        4          2024-01-22 13:28:46 +0000 UTC   <none>

PVのデータが復旧しているか試します。

# curl -X GET http://registry.tsuchinokometal.com/v2/_catalog
{"repositories":["nginx"]}

リストアできた!