use deployment for manual backup restore

This commit is contained in:
Michael Jerger 2021-10-01 13:43:37 +00:00
parent 2966c2f0bf
commit 6115b0a121
11 changed files with 96 additions and 82 deletions

View file

@ -33,7 +33,7 @@ target/graalvm/c4k-jira src/test/resources/valid-config.edn src/test/resources/v
## Documentation ## Documentation
* [Example Setup on Hetzner](doc/SetupOnHetzner.md) * [Example Setup on Hetzner](doc/SetupOnHetzner.md)
* [Backup and Restore](doc/BackupAndResotre.md) * [Backup and Restore](doc/BackupAndRestore.md)
## License ## License

View file

@ -10,40 +10,40 @@
## Manual init the restic repository for the first time ## Manual init the restic repository for the first time
1. apply backup-and-restore pod: 1. apply backup-and-restore pod:
`kubectl apply -f src/main/resources/backup/backup-restore.yaml` `kubectl scale deployment backup-restore --replicas=1`
1. exec into pod and execute restore pod 1. exec into pod and execute restore pod (press tab to get your exact pod name)
`kubectl exec -it backup-restore -- /usr/local/bin/init.sh` `kubectl exec -it backup-restore-... -- /usr/local/bin/init.sh`
1. remove backup-and-restore pod: 1. remove backup-and-restore pod:
`kubectl delete pod backup-restore `kubectl scale deployment backup-restore --replicas=0`
## Manual backup the restic repository for the first time ## Manual backup the restic repository for the first time
1.Create a jira export: 1.Create a jira export:
Jira > Settings > System -> Backup system Jira > Settings > System -> Backup system
1. Choose a filename `backup-filename.xml`. Your file will be stored to `/var/backup/export`. 1. Choose a filename `backup-filename.zip`. Your file will be stored to `/var/backup/export`.
1. apply backup-and-restore pod: 1. apply backup-and-restore pod:
`kubectl apply -f src/main/resources/backup/backup-restore.yaml` `kubectl scale deployment backup-restore --replicas=1`
1. exec into pod and execute restore pod 1. exec into pod and execute restore pod (press tab to get your exact pod name)
`kubectl exec -it backup-restore -- /usr/local/bin/backup.sh` `kubectl exec -it backup-restore-... -- /usr/local/bin/backup.sh`
1. remove backup-and-restore pod: 1. remove backup-and-restore pod:
`kubectl delete pod backup-restore` `kubectl scale deployment backup-restore --replicas=0`
## Manual restore ## Manual restore
1. apply backup-and-restore pod: 1. apply backup-and-restore pod:
`kubectl apply -f src/main/resources/backup/backup-restore.yaml` `kubectl scale deployment backup-restore --replicas=1`
1. exec into pod and execute restore pod 1. exec into pod and execute restore pod (press tab to get your exact pod name)
`kubectl exec -it backup-restore -- /usr/local/bin/restore.sh` `kubectl exec -it backup-restore-... -- /usr/local/bin/restore.sh`
1. In case of already set up server: 1. In case of already set up server:
1. Import one of Jira exportet backups: 1. Import one of Jira exportet backups:
Jira > Settings > System > Restore System Jira > Settings > System > Restore System
1. Choose one of your bakcuped files located at `/var/jira/restic-restore/export/`. 1. Choose one of your backuped files located at `/var/jira/import/`.
E.g. `/var/jira/restic-restore/export/backup-filename.xml`. E.g. `backup-filename.zip`.
1. In case of installation wizzard: 1. In case of installation wizzard:
1. Choose restore from backup 1. Choose restore from backup
1. Choose one of your bakcuped files located at `/var/jira/restic-restore/export/`. 1. Choose one of your backuped files located at `/var/jira/import/`.
E.g. `/var/jira/restic-restore/export/backup-filename.xml` E.g. `backup-filename.zip`
1. remove backup-and-restore pod: 1. remove backup-and-restore pod:
`kubectl delete pod backup-restore` `kubectl scale deployment backup-restore --replicas=0`

View file

@ -7,8 +7,7 @@ function main() {
file_env AWS_SECRET_ACCESS_KEY file_env AWS_SECRET_ACCESS_KEY
file_env RESTIC_DAYS_TO_KEEP 14 file_env RESTIC_DAYS_TO_KEEP 14
backup-roles "" backup-fs-from-directory '/var/backups/' 'export/'
backup-fs-from-directory '/var/backups/' 'data/'
} }
source /usr/local/lib/functions.sh source /usr/local/lib/functions.sh

View file

@ -7,15 +7,12 @@ function main() {
file_env AWS_ACCESS_KEY_ID file_env AWS_ACCESS_KEY_ID
file_env AWS_SECRET_ACCESS_KEY file_env AWS_SECRET_ACCESS_KEY
# Restore latest snapshot into /var/backups/restic-restore # Restore latest snapshot into /var/backups/restore
rm -rf /var/backups/restic-restore rm -rf /var/backups/restore
restore-directory '/var/backups/restic-restore' restore-directory '/var/backups/restore'
# Restore data dir backup cp /var/backups/restore/export/*.zip /var/backups/import/
rm -rf /var/backups/data/* chown 901:901 /var/backups/import/*.zip
cp -a /var/backups/restic-restore/data/* /var/backups/data
# /opt/atlassian-jira-software-standalone/bin/start-jira.sh
} }
source /usr/local/lib/functions.sh source /usr/local/lib/functions.sh

View file

@ -1,5 +1,8 @@
FROM c4k-jira-backup FROM c4k-jira-backup
RUN apt update
RUN apt -yqq --no-install-recommends --yes install curl default-jre-headless
RUN curl -L -o /tmp/serverspec.jar \ RUN curl -L -o /tmp/serverspec.jar \
https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar

View file

@ -4,12 +4,13 @@
#?(:cljs [shadow.resource :as rc]) #?(:cljs [shadow.resource :as rc])
[dda.c4k-common.yaml :as yaml] [dda.c4k-common.yaml :as yaml]
[dda.c4k-common.base64 :as b64] [dda.c4k-common.base64 :as b64]
[dda.c4k-common.common :as cm])) [dda.c4k-common.common :as cm]
[dda.c4k-common.prefixes :as pf]))
(s/def ::aws-access-key-id cm/bash-env-string?) (s/def ::aws-access-key-id pf/bash-env-string?)
(s/def ::aws-secret-access-key cm/bash-env-string?) (s/def ::aws-secret-access-key pf/bash-env-string?)
(s/def ::restic-password cm/bash-env-string?) (s/def ::restic-password pf/bash-env-string?)
(s/def ::restic-repository cm/bash-env-string?) (s/def ::restic-repository pf/bash-env-string?)
#?(:cljs #?(:cljs
(defmethod yaml/load-resource :backup [resource-name] (defmethod yaml/load-resource :backup [resource-name]
@ -17,6 +18,7 @@
"backup/config.yaml" (rc/inline "backup/config.yaml") "backup/config.yaml" (rc/inline "backup/config.yaml")
"backup/cron.yaml" (rc/inline "backup/cron.yaml") "backup/cron.yaml" (rc/inline "backup/cron.yaml")
"backup/secret.yaml" (rc/inline "backup/secret.yaml") "backup/secret.yaml" (rc/inline "backup/secret.yaml")
"backup/backup-restore-deployment.yaml" (rc/inline "backup/backup-restore-deployment.yaml")
(throw (js/Error. "Undefined Resource!"))))) (throw (js/Error. "Undefined Resource!")))))
(defn generate-config [my-conf] (defn generate-config [my-conf]
@ -28,6 +30,9 @@
(defn generate-cron [] (defn generate-cron []
(yaml/from-string (yaml/load-resource "backup/cron.yaml"))) (yaml/from-string (yaml/load-resource "backup/cron.yaml")))
(defn generate-backup-restore-deployment []
(yaml/from-string (yaml/load-resource "backup/backup-restore-deployment.yaml")))
(defn generate-secret [my-auth] (defn generate-secret [my-auth]
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth] (let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth]
(-> (->

View file

@ -39,7 +39,8 @@
(when (contains? config :restic-repository) (when (contains? config :restic-repository)
[(yaml/to-string (backup/generate-config config)) [(yaml/to-string (backup/generate-config config))
(yaml/to-string (backup/generate-secret config)) (yaml/to-string (backup/generate-secret config))
(yaml/to-string (backup/generate-cron))])))) (yaml/to-string (backup/generate-cron))
(yaml/to-string (backup/generate-backup-restore-deployment))]))))
(defn-spec generate any? (defn-spec generate any?
[my-config config? [my-config config?

View file

@ -15,11 +15,11 @@
(br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository" "dda.c4k_jira.browser") (br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository" "dda.c4k_jira.browser")
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "" "dda.c4k_jira.browser") (br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "" "dda.c4k_jira.browser")
[(br/generate-br)] [(br/generate-br)]
(br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \" jira \" (br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"jira\"
:postgres-db-password \" jira-db-password \" :postgres-db-password \"jira-db-password\"
:aws-access-key-id \" aws-id \" :aws-access-key-id \"aws-id\"
:aws-secret-access-key \" aws-secret \" :aws-secret-access-key \"aws-secret\"
:restic-password \" restic-password \"}" :restic-password \"restic-password\"}"
"5" "dda.c4k_jira.browser") "5" "dda.c4k_jira.browser")
[(br/generate-br)] [(br/generate-br)]
(br/generate-button "generate-button" "Generate c4k yaml"))))] (br/generate-button "generate-button" "Generate c4k yaml"))))]

View file

@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backup-restore
spec:
replicas: 0
selector:
matchLabels:
app: backup-restore
strategy:
type: Recreate
template:
metadata:
labels:
app: backup-restore
app.kubernetes.io/name: backup-restore
app.kubernetes.io/part-of: jira
spec:
containers:
- image: domaindrivenarchitecture/c4k-jira-backup
name: backup-app
imagePullPolicy: IfNotPresent
command: ["/entrypoint-start-and-wait.sh"]
env:
- name: AWS_DEFAULT_REGION
value: eu-central-1
- name: AWS_ACCESS_KEY_ID_FILE
value: /var/run/secrets/backup-secrets/aws-access-key-id
- name: AWS_SECRET_ACCESS_KEY_FILE
value: /var/run/secrets/backup-secrets/aws-secret-access-key
- name: RESTIC_REPOSITORY
valueFrom:
configMapKeyRef:
name: backup-config
key: restic-repository
- name: RESTIC_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-password
volumeMounts:
- name: jira-data-volume
mountPath: /var/backups
- name: backup-secret-volume
mountPath: /var/run/secrets/backup-secrets
readOnly: true
volumes:
- name: jira-data-volume
persistentVolumeClaim:
claimName: jira-pvc
- name: backup-secret-volume
secret:
secretName: backup-secret

View file

@ -1,41 +0,0 @@
kind: Pod
apiVersion: v1
metadata:
name: backup-restore
labels:
app.kubernetes.io/name: backup-restore
app.kubernetes.io/part-of: jira
spec:
containers:
- name: backup-app
image: domaindrivenarchitecture/c4k-jira-backup
imagePullPolicy: IfNotPresent
command: ["/entrypoint-start-and-wait.sh"]
env:
- name: AWS_DEFAULT_REGION
value: eu-central-1
- name: AWS_ACCESS_KEY_ID_FILE
value: /var/run/secrets/backup-secrets/aws-access-key-id
- name: AWS_SECRET_ACCESS_KEY_FILE
value: /var/run/secrets/backup-secrets/aws-secret-access-key
- name: RESTIC_REPOSITORY
valueFrom:
configMapKeyRef:
name: backup-config
key: restic-repository
- name: RESTIC_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-password
volumeMounts:
- name: jira-data-volume
mountPath: /var/backups
- name: backup-secret-volume
mountPath: /var/run/secrets/backup-secrets
readOnly: true
volumes:
- name: jira-data-volume
persistentVolumeClaim:
claimName: jira-pvc
- name: backup-secret-volume
secret:
secretName: backup-secret
restartPolicy: OnFailure

View file

@ -5,7 +5,7 @@
[dda.c4k-jira.core :as cut])) [dda.c4k-jira.core :as cut]))
(deftest should-k8s-objects (deftest should-k8s-objects
(is (= 15 (is (= 16
(count (cut/k8s-objects {:fqdn "jira-neu.prod.meissa-gmbh.de" (count (cut/k8s-objects {:fqdn "jira-neu.prod.meissa-gmbh.de"
:postgres-db-user "jira" :postgres-db-user "jira"
:postgres-db-password "jira-db-password" :postgres-db-password "jira-db-password"
@ -16,7 +16,7 @@
:aws-secret-access-key "aws-secret" :aws-secret-access-key "aws-secret"
:restic-password "restic-pw" :restic-password "restic-pw"
:restic-repository "restic-repository"})))) :restic-repository "restic-repository"}))))
(is (= 13 (is (= 14
(count (cut/k8s-objects {:fqdn "jira-neu.prod.meissa-gmbh.de" (count (cut/k8s-objects {:fqdn "jira-neu.prod.meissa-gmbh.de"
:postgres-db-user "jira" :postgres-db-user "jira"
:postgres-db-password "jira-db-password" :postgres-db-password "jira-db-password"