From 0da9cbb4094e498d452dc5f480159c9c340d24c3 Mon Sep 17 00:00:00 2001 From: Manabu McCloskey Date: Thu, 18 Jan 2024 21:29:43 +0000 Subject: [PATCH] add restore section Signed-off-by: Manabu McCloskey --- examples/local-backup/README.md | 73 ++++++++++++++-- examples/local-backup/demo/restore.yaml | 10 +++ examples/local-backup/minio/helm/values.yaml | 6 +- .../minio/manifests/secret-sync.yaml | 84 +++++++++++++------ 4 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 examples/local-backup/demo/restore.yaml diff --git a/examples/local-backup/README.md b/examples/local-backup/README.md index d6c06690..0673822b 100644 --- a/examples/local-backup/README.md +++ b/examples/local-backup/README.md @@ -16,17 +16,17 @@ Take a look at the [kind.yaml](./kind.yaml) file. The most relevant part is this ```yaml nodes: -- role: control-plane - extraMounts: - - hostPath: /home/ubuntu/backup # replace with your own path - containerPath: /backup + - role: control-plane + extraMounts: + - hostPath: /home/ubuntu/backup # replace with your own path + containerPath: /backup ``` This instructs Kind to make your machine's directory at `/home/ubuntu/backup` -available at `/backup` for the Kubernetes node. +available at `/backup` for the Kubernetes node. You **must** change this value for your own setup. This directory also must exist on your machine. -For example, you may want to change it to `/Users/my-name/backup`. +For example, you may want to change it to `/Users/my-name/backup`. Once you've made the change, run this command from the root of this repository. @@ -73,7 +73,9 @@ Once you log in, you will notice a bucket is already created for you. Velero wil ![image](./images/bucket.png) -Let's try creating a backup of an example application. +### Backup + +Let's try creating a backup of an example application. First, create an example nginx app straight from the velero repository. @@ -111,5 +113,62 @@ drwxr-xr-x 2 ubuntu ubuntu 4.0K Jan 18 01:25 nginx-backup.tar.gz drwxr-xr-x 2 ubuntu ubuntu 4.0K Jan 18 01:25 velero-backup.json ``` +### Restore + +Let's simulate a cluster loss by deleting the kind cluster forcibly. + +```bash +kind delete clusters localdev && docker system prune -f +``` + +Once it is destroyed, create it again. + +```bash +idpbuilder create --kind-config examples/local-backup/kind.yaml --kind-config examples/local-backup/kind.yaml +``` + +Make sure everything looks good: + +```bash +$ kubectl get application -n argocd +NAME SYNC STATUS HEALTH STATUS +argocd Synced Healthy +gitea Synced Healthy +minio Synced Healthy +nginx Synced Healthy +velero Synced Healthy +``` + +Let's make sure Velero can validate the minio bucket: +```bash +$ kubectl get backupstoragelocations.velero.io -n velero +NAME PHASE LAST VALIDATED AGE DEFAULT +default Available 4s 52m true +``` + +Looks good. Let's make sure the backup from the destroyed cluster is available. + +```bash +$ kubectl get backup -n velero +NAME AGE +nginx-backup 1m +``` + +Target this backup to restore objects. + +```bash +kubectl apply -f examples/local-backup/demo/restore.yaml +``` + +This command is equivalent to `velero restore create --from-backup nginx-backup`. + +Verify everything was restored: +```bash +$ kubectl get backup -n velero -o custom-columns="NAME":.metadata.name,"PHASE":.status.phase +NAME PHASE +nginx-backup Completed + +$ kubectl get pods -n nginx-example +``` diff --git a/examples/local-backup/demo/restore.yaml b/examples/local-backup/demo/restore.yaml new file mode 100644 index 00000000..addf02ba --- /dev/null +++ b/examples/local-backup/demo/restore.yaml @@ -0,0 +1,10 @@ +# /velero restore create --from-backup nginx-backup +apiVersion: velero.io/v1 +kind: Restore +metadata: + name: nginx-backup + namespace: velero +spec: + backupName: nginx-backup + includedNamespaces: + - '*' \ No newline at end of file diff --git a/examples/local-backup/minio/helm/values.yaml b/examples/local-backup/minio/helm/values.yaml index 34e78cea..03d0ccd4 100644 --- a/examples/local-backup/minio/helm/values.yaml +++ b/examples/local-backup/minio/helm/values.yaml @@ -20,8 +20,4 @@ consoleIngress: hosts: - minio.cnoe.localtest.me -users: - - accessKey: velero-access-key - existingSecret: secret-key - existingSecretKey: secret-key - policy: consoleAdmin +existingSecret: root-creds diff --git a/examples/local-backup/minio/manifests/secret-sync.yaml b/examples/local-backup/minio/manifests/secret-sync.yaml index 6760b04e..2872bccc 100644 --- a/examples/local-backup/minio/manifests/secret-sync.yaml +++ b/examples/local-backup/minio/manifests/secret-sync.yaml @@ -4,8 +4,8 @@ metadata: name: secret-sync namespace: minio annotations: - argocd.argoproj.io/sync-wave: "-10" - + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-20" --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -13,8 +13,8 @@ metadata: name: secret-sync namespace: minio annotations: - argocd.argoproj.io/sync-wave: "-10" - + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-20" rules: - apiGroups: [""] resources: ["secrets"] @@ -26,7 +26,8 @@ metadata: name: secret-sync namespace: minio annotations: - argocd.argoproj.io/sync-wave: "-10" + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-20" subjects: - kind: ServiceAccount name: secret-sync @@ -42,7 +43,8 @@ metadata: name: secret-sync namespace: velero annotations: - argocd.argoproj.io/sync-wave: "-10" + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-20" rules: - apiGroups: [""] resources: ["secrets"] @@ -54,7 +56,8 @@ metadata: name: secret-sync namespace: velero annotations: - argocd.argoproj.io/sync-wave: "-10" + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-20" subjects: - kind: ServiceAccount name: secret-sync @@ -70,8 +73,7 @@ metadata: name: secret-sync namespace: minio annotations: - argocd.argoproj.io/hook: Sync - argocd.argoproj.io/sync-wave: "-5" + argocd.argoproj.io/hook: PostSync spec: template: metadata: @@ -85,40 +87,68 @@ spec: command: ["/bin/bash", "-c"] args: - | - kubectl get secrets -n velero secret-key - if [ $? -eq 0 ]; then - exit 0 - fi - - set -ex - - randString=$(openssl rand -base64 24) + set -e + kubectl get secrets -n minio root-creds -o json > /tmp/secret + ACCESS=$(jq -r '.data.rootUser | @base64d' /tmp/secret) + SECRET=$(jq -r '.data.rootPassword | @base64d' /tmp/secret) echo \ "apiVersion: v1 kind: Secret metadata: name: secret-key - namespace: minio + namespace: velero type: Opaque stringData: - secret-key: ${randString} + aws: | + [default] + aws_access_key_id=${ACCESS} + aws_secret_access_key=${SECRET} " > /tmp/secret.yaml - + kubectl apply -f /tmp/secret.yaml +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: minio-root-creds + namespace: minio + annotations: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/sync-wave: "-10" +spec: + template: + metadata: + generateName: minio-root-creds + spec: + serviceAccountName: secret-sync + restartPolicy: Never + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + command: ["/bin/bash", "-c"] + args: + - | + kubectl get secrets -n minio root-creds + if [ $? -eq 0 ]; then + exit 0 + fi + + set -e + + NAME=$(openssl rand -base64 24) + PASS=$(openssl rand -base64 36) echo \ "apiVersion: v1 kind: Secret metadata: - name: secret-key - namespace: velero + name: root-creds + namespace: minio type: Opaque stringData: - aws: | - [default] - aws_access_key_id=velero-access-key - aws_secret_access_key=${randString} + rootUser: "${NAME}" + rootPassword: "${PASS}" " > /tmp/secret.yaml - kubectl apply -f /tmp/secret.yaml \ No newline at end of file + kubectl apply -f /tmp/secret.yaml