diff --git a/docs/modules/ROOT/pages/how-tos/restore.adoc b/docs/modules/ROOT/pages/how-tos/restore.adoc new file mode 100644 index 00000000..21c8ffdc --- /dev/null +++ b/docs/modules/ROOT/pages/how-tos/restore.adoc @@ -0,0 +1,145 @@ += Restore Keycloak from a Backup + +The following steps will guide you through restoring a backup of Keycloak. + +[IMPORTANT] +==== +This guide only covers how to restore the built-in database. +If you use an external database, please consult the documentation of your database provider on how to backup and restore it. +==== + +[NOTE] +==== +You can only restore a database that has been backed up. +Please refer to the xref:how-tos/use-built-in-db.adoc#_enable_backups[built-in database] setup guide on how to enable backups. +==== + +==== +Requirements + +* `kubectl` With access to the cluster running Keycloak +* `base64` +* https://restic.net/[`restic`] +* (optional) https://stedolan.github.io/jq/[`jq`] +* `pwgen` +* `vault` +==== + +. Configure access to backups ++ +[source,bash] +---- +# The namspace containing the Keycloak instance. Change if necessary. +export NAMESPACE=syn-keycloak + +export reposecret=$( \ + kubectl -n $NAMESPACE get schedule backup \ + -o go-template="{{.spec.backend.repoPasswordSecretRef.name}}" \ + ) +export s3secret=$( \ + kubectl -n $NAMESPACE get schedule backup \ + -o jsonpath="{.spec.backend.s3.accessKeyIDSecretRef.name}" \ + ) + +export RESTIC_REPOSITORY=$( \ + kubectl -n $NAMESPACE get schedule backup \ + -o go-template="s3:{{.spec.backend.s3.endpoint}}/{{.spec.backend.s3.bucket}}/" \ + ) +export RESTIC_PASSWORD=$( \ + kubectl -n $NAMESPACE get secrets $reposecret \ + -o jsonpath={.data.password} \ + | base64 -d \ + ) +export AWS_ACCESS_KEY_ID=$( \ + kubectl -n $NAMESPACE get secrets $s3secret \ + -o jsonpath="{.data.username}" \ + | base64 -d \ + ) +export AWS_SECRET_ACCESS_KEY=$( \ + kubectl -n $NAMESPACE get secrets $s3secret \ + -o jsonpath="{.data.password}" \ + | base64 -d \ + ) +---- + +. List backups and choose the one to restore ++ +[source,bash] +---- +restic snapshots + +export SNAPSHOT_ID=XXXXXX # Choose a snapshot id from the list +---- ++ +[TIP] +==== +To choose the last available backup you can simply run +[source,bash] +---- +export SNAPSHOT_ID=$(restic snapshots --json --latest 1 --path /$NAMESPACE-keycloak-postgresql.sql | jq -r '.[0].id') +---- +==== + +. Disable ArgoCD auto sync ++ +[source,bash] +---- +# The ArgoCD app of the Keycloak instance. Change if necessary. +export ARGO_APP=keycloak + +kubectl -n syn patch apps root --type=json \ + -p '[{"op":"replace", "path":"/spec/syncPolicy", "value": {}}]' +kubectl -n syn patch apps ${ARGO_APP} --type=json \ + -p '[{"op":"replace", "path":"/spec/syncPolicy", "value": {}}]' +---- + +. Scale down Keycloak ++ +[source,bash] +---- +kubectl -n $NAMESPACE patch statefulset keycloak --type=json \ + -p '[{"op":"replace", "path":"/spec/replicas", "value": 0}]' + +# Wait until statefulset has been scaled down +kubectl -n $NAMESPACE get statefulset keycloak -w +---- + +. Load the backup and restore it ++ +[source,bash] +---- +export POD=keycloak-postgresql-0 + +restic dump "${SNAPSHOT_ID}" /$NAMESPACE-keycloak-postgresql.sql \ + | kubectl -n $NAMESPACE exec -i $POD \ + -- sh -c 'PGPASSWORD="${POSTGRES_PASSWORD}" psql --set ON_ERROR_STOP=on -U "${POSTGRES_USER}" ${POSTGRES_DB}' +---- + +. Re-enable ArgoCD auto sync and scale up Keycloak ++ +[source,bash] +---- +kubectl -n syn patch apps root --type=json \ + -p '[{ + "op":"replace", + "path":"/spec/syncPolicy", + "value": {"automated": {"prune": true, "selfHeal": true}} + }]' + +# Wait until Keycloak has started sucessfully +kubectl -n $NAMESPACE get statefulset keycloak -w +---- + +[NOTE] +==== +This guide assumes that you have direct access to the S3 bucket holding the backup. +If the access is restricted to the Kubernetes cluster, you will need to adapt these steps. +You could: + +. Perform the commands in a container running on the cluster +. Restore the database backup to a PVC and copy it over + +Consult the official https://k8up.io/k8up/2.1/how-tos/restore.html#_restore_from_s3_to_pvc[K8up documentation] on options for restoring backups. +==== + + diff --git a/docs/modules/ROOT/pages/how-tos/use-built-in-db.adoc b/docs/modules/ROOT/pages/how-tos/use-built-in-db.adoc index 9f0e0f7d..be3498fc 100644 --- a/docs/modules/ROOT/pages/how-tos/use-built-in-db.adoc +++ b/docs/modules/ROOT/pages/how-tos/use-built-in-db.adoc @@ -36,3 +36,59 @@ vault kv put -cas=0 "${key}" admin-password=$(pwgen -s 32 1) db-password=$(pwgen ---- . Compile and push the cluster catalog + +== Enable Backups + +The component supports backups for the built-in database through https://k8up.io/[K8up]. +The following steps show how to enable them. + +[NOTE] +==== +To use this backup feature, the https://github.com/projectsyn/component-backup-k8up[component-backup-k8up] needs to be installed on the cluster. +==== + +. Enable backups in component parameters ++ +[source,yaml] +---- +keycloak: + k8up: + enabled: true +---- + +. Generate and store repository secret in Vault ++ +[source,bash] +---- +key="clusters/kv/${TENANT_ID}/${CLUSTER_ID}/keycloak" + +vault kv patch "${key}" k8up-repo-password=$(pwgen -s 32 1) +---- + +. Get the access and secret key of your S3 provider and store them in Vault ++ +[source,bash] +---- +s3_access_key=YOUR_ACCESS_KEY +s3_secret_key=YOUR_SECRET_KEY +key="clusters/kv/${TENANT_ID}/${CLUSTER_ID}/keycloak" + +vault kv patch "${key}" k8up-s3-accesskey=${s3_access_key} k8up-s3-secretkey=${s3_secret_key} k8up-repo-password=$(pwgen -s 32 1) +---- ++ +[TIP] +==== +On most clusters you should be able to reuse the global backup credentials set up during cluster creation. +Just add a reference to the credentials in Vault to the K8up S3 configuration and you can skip this step. + +[source,yaml] +---- +keycloak: + k8up: + enabled: true + s3: + accesskey: '?{vaultkv:${customer:name}/${cluster:name}/global-backup/access-key}' + secretkey: '?{vaultkv:${customer:name}/${cluster:name}/global-backup/secret-key}' +---- +==== + diff --git a/docs/modules/ROOT/partials/nav.adoc b/docs/modules/ROOT/partials/nav.adoc index 8f3420cd..47a2384f 100644 --- a/docs/modules/ROOT/partials/nav.adoc +++ b/docs/modules/ROOT/partials/nav.adoc @@ -12,6 +12,7 @@ * xref:how-tos/configure-ingress.adoc[Configure Keycloak ingress] * xref:how-tos/custom-theme.adoc[Configure custom theme] * xref:how-tos/change-passwords.adoc[Change passwords] +* xref:how-tos/restore.adoc[Restore from a Backup] * xref:how-tos/upgrade-1.x-to-2.x.adoc[Upgrade 1.x to 2.x] * xref:how-tos/upgrade-2.x-to-3.x.adoc[Upgrade 2.x to 3.x] * xref:how-tos/upgrade-3.x-to-4.x.adoc[Upgrade 3.x to 4.x]