Merge branch 'use-deployment-for-backup-restore' into 'main'
use deployment for manual backup restore See merge request domaindrivenarchitecture/c4k-jira!1
This commit is contained in:
commit
082f1e945e
11 changed files with 96 additions and 82 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
(->
|
(->
|
||||||
|
|
|
@ -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?
|
||||||
|
|
50
src/main/resources/backup/backup-restore-deployment.yaml
Normal file
50
src/main/resources/backup/backup-restore-deployment.yaml
Normal 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
|
|
@ -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
|
|
|
@ -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"
|
||||||
|
|
Reference in a new issue