From 8af25bdd7b39c41dd7d72f2f4f349f98a476d45d Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Thu, 1 Jun 2023 16:35:51 +0200 Subject: [PATCH 1/9] feat(kubernetes): example cronjob & container image creation Signed-off-by: Toni Tauro --- kubernetes/Dockerfile | 12 +++++++++++ kubernetes/README.md | 19 +++++++++++++++++ kubernetes/cronjob.yaml | 46 ++++++++++++++++++++++++++++++++++++++++ kubernetes/entrypoint.sh | 19 +++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 kubernetes/Dockerfile create mode 100644 kubernetes/README.md create mode 100644 kubernetes/cronjob.yaml create mode 100644 kubernetes/entrypoint.sh diff --git a/kubernetes/Dockerfile b/kubernetes/Dockerfile new file mode 100644 index 0000000..f6df990 --- /dev/null +++ b/kubernetes/Dockerfile @@ -0,0 +1,12 @@ +FROM alpine + +ARG VAULT_VERSION=1.13.2 + +COPY entrypoint.sh / + +RUN wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip && \ + unzip vault_${VAULT_VERSION}_linux_amd64.zip && \ + mv vault /usr/local/bin && rm vault*zip && \ + apk add s3cmd && chmod +x entrypoint.sh + +ENTRYPOINT /entrypoint.sh diff --git a/kubernetes/README.md b/kubernetes/README.md new file mode 100644 index 0000000..e2b1ac6 --- /dev/null +++ b/kubernetes/README.md @@ -0,0 +1,19 @@ +# Cronjob for snapshoting a vault running on Kubernetes + +This assumes kubernetes authentication backend is configured on vault. + +The container image being used in this cronjob, is authenticating to Vault with the kubernetes authentication backend, with its serviceaccount JWT. + +The role and policy being used must be created before hand and must be used by the cronjob. + +After the snapshot is created in a temporary directory, `s3cmd` is used to sync it to a s3 endpoint. + +## Configuration over environment variables + +* `VAULT_ADDR` - Vault address to access +* `VAULT_ROLE` - Vault role to use to create the snapshot +* `S3_URI` - S3 URI to use to upload (s3://xxx) +* `S3_BUCKET` - S3 bucket to point to +* `S3_HOST` - S3 endpoint +* `AWS_ACCESS_KEY_ID` - Access key to use to access S3 +* `AWS_SECRET_ACCESS_KEY` - Secret access key to use to access S3 diff --git a/kubernetes/cronjob.yaml b/kubernetes/cronjob.yaml new file mode 100644 index 0000000..2d8292b --- /dev/null +++ b/kubernetes/cronjob.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + labels: + app.kubernetes.io/name: vault-snapshot + app.kubernetes.io/version: v0.1.0 + name: vault-snapshot +spec: + jobTemplate: + metadata: + labels: + app.kubernetes.io/name: vault-snapshot + app.kubernetes.io/version: v0.1.0 + spec: + template: + metadata: + labels: + app.kubernetes.io/name: vault-snapshot + app.kubernetes.io/version: v0.1.0 + spec: + containers: + - name: vault-snapshot + env: + - name: S3_HOST + value: s3.example.com + - name: S3_BUCKET + value: bucketname + - name: S3_URI + value: s3://bucketname + - name: VAULT_ROLE + value: vault-snapshot + - name: VAULT_ADDR + value: https://vault.example.com + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + key: aws_secret_access_key + name: vault-snapshot-credentials + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + key: aws_access_key_id + name: vault-snapshot-credentials + image: ghcr.io/adfinis/vault-snapshot:0.1.-0 + imagePullPolicy: IfNotPresent diff --git a/kubernetes/entrypoint.sh b/kubernetes/entrypoint.sh new file mode 100644 index 0000000..88bf550 --- /dev/null +++ b/kubernetes/entrypoint.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +# create tmpdir + +mkdir -p /tmp/vault-snapshots + +# authenticate using kubernetes auth +export JWT=$(cat /var/run/secrets/kubernetes/io/serviceaccount/token) +export VAULT_TOKEN=$(vault write -field=token auth/kubernetes/login role=$VAULT_ROLE jwt=$JWT) + +# use the leader node as VAULT_ADDR +export VAULT_ADDR=$(vault status -format=yaml | egrep -o '^leader_addr.*' | awk '{print $2}') + +# create snapshot + +vault operator raft snapshot save /tmp/vault-snapshots/vault_$(date +%F-%H%M).snapshot + +# upload to s3 +s3cmd put /tmp/vault-snapshots/* $S3_URI --host=$S3_HOST --host-bucket=$S3_BUCKET From d1fe020573641c24acff91f873602f66e1553557 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Thu, 1 Jun 2023 16:40:08 +0200 Subject: [PATCH 2/9] fix(cronjob): add schedule, doh Signed-off-by: Toni Tauro --- kubernetes/cronjob.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/kubernetes/cronjob.yaml b/kubernetes/cronjob.yaml index 2d8292b..969366d 100644 --- a/kubernetes/cronjob.yaml +++ b/kubernetes/cronjob.yaml @@ -8,6 +8,7 @@ metadata: name: vault-snapshot spec: jobTemplate: + schedule: 0 4 * * * metadata: labels: app.kubernetes.io/name: vault-snapshot From 92c42e5efe0af42b62d1994184ba723a6119bfb7 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:09:30 +0200 Subject: [PATCH 3/9] Update kubernetes/README.md Co-authored-by: Lukas Grossar --- kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index e2b1ac6..efd17d3 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,4 +1,4 @@ -# Cronjob for snapshoting a vault running on Kubernetes +# Cronjob for snapshotting Vault running on Kubernetes This assumes kubernetes authentication backend is configured on vault. From 75011d42c6b4aefc1d4f95b634ba4920c55294b4 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:09:43 +0200 Subject: [PATCH 4/9] Update kubernetes/README.md Co-authored-by: Lukas Grossar --- kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index efd17d3..945b5b8 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,6 +1,6 @@ # Cronjob for snapshotting Vault running on Kubernetes -This assumes kubernetes authentication backend is configured on vault. +This assumes the Kubernetes authentication backend is configured in Vault. The container image being used in this cronjob, is authenticating to Vault with the kubernetes authentication backend, with its serviceaccount JWT. From 811c9cdb2d32219e9d48974a07c897c16bcc1da7 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:09:59 +0200 Subject: [PATCH 5/9] Update kubernetes/README.md Co-authored-by: Lukas Grossar --- kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 945b5b8..adf2b14 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -2,7 +2,7 @@ This assumes the Kubernetes authentication backend is configured in Vault. -The container image being used in this cronjob, is authenticating to Vault with the kubernetes authentication backend, with its serviceaccount JWT. +The script being executed in this cronjob, is authenticating with Vault using the Kubernetes authentication backend, via its serviceaccount JWT. The role and policy being used must be created before hand and must be used by the cronjob. From def472fb344491afaebedac043108fd1e7039db8 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:10:27 +0200 Subject: [PATCH 6/9] Update kubernetes/cronjob.yaml Co-authored-by: Lukas Grossar --- kubernetes/cronjob.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kubernetes/cronjob.yaml b/kubernetes/cronjob.yaml index 969366d..cfdcf90 100644 --- a/kubernetes/cronjob.yaml +++ b/kubernetes/cronjob.yaml @@ -45,3 +45,6 @@ spec: name: vault-snapshot-credentials image: ghcr.io/adfinis/vault-snapshot:0.1.-0 imagePullPolicy: IfNotPresent + volumes: + - name: backup-dir + emptyDir: {} From 2b1d8d2027b4788217570c6c0a4d51403898a21e Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:10:48 +0200 Subject: [PATCH 7/9] Update kubernetes/cronjob.yaml Co-authored-by: Lukas Grossar --- kubernetes/cronjob.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubernetes/cronjob.yaml b/kubernetes/cronjob.yaml index cfdcf90..e18e023 100644 --- a/kubernetes/cronjob.yaml +++ b/kubernetes/cronjob.yaml @@ -20,6 +20,8 @@ spec: app.kubernetes.io/name: vault-snapshot app.kubernetes.io/version: v0.1.0 spec: + automountServiceAccountToken: true + serviceAccountName: vault-raft-backup containers: - name: vault-snapshot env: From f5d9b72984467fbce2443e5f8d654ec1a3a0e309 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 09:15:51 +0200 Subject: [PATCH 8/9] feat(cronjob/sa/script): suggestions from @lukasgr Signed-off-by: Toni Tauro --- kubernetes/cronjob.yaml | 11 +++++++---- kubernetes/serviceaccount.yaml | 5 +++++ kubernetes/{entrypoint.sh => vault-snapshot.sh} | 8 ++------ 3 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 kubernetes/serviceaccount.yaml rename kubernetes/{entrypoint.sh => vault-snapshot.sh} (64%) diff --git a/kubernetes/cronjob.yaml b/kubernetes/cronjob.yaml index e18e023..97b1fbc 100644 --- a/kubernetes/cronjob.yaml +++ b/kubernetes/cronjob.yaml @@ -21,7 +21,7 @@ spec: app.kubernetes.io/version: v0.1.0 spec: automountServiceAccountToken: true - serviceAccountName: vault-raft-backup + serviceAccountName: vault-raft-snapshot containers: - name: vault-snapshot env: @@ -46,7 +46,10 @@ spec: key: aws_access_key_id name: vault-snapshot-credentials image: ghcr.io/adfinis/vault-snapshot:0.1.-0 + volumeMounts: + - name: snapshot-dir + mountPath: /vault-snaphots imagePullPolicy: IfNotPresent - volumes: - - name: backup-dir - emptyDir: {} + volumes: + - name: snapshot-dir + emptyDir: {} diff --git a/kubernetes/serviceaccount.yaml b/kubernetes/serviceaccount.yaml new file mode 100644 index 0000000..0860761 --- /dev/null +++ b/kubernetes/serviceaccount.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault-raft-snapshot diff --git a/kubernetes/entrypoint.sh b/kubernetes/vault-snapshot.sh similarity index 64% rename from kubernetes/entrypoint.sh rename to kubernetes/vault-snapshot.sh index 88bf550..5463438 100644 --- a/kubernetes/entrypoint.sh +++ b/kubernetes/vault-snapshot.sh @@ -1,9 +1,5 @@ #!/usr/bin/env sh -# create tmpdir - -mkdir -p /tmp/vault-snapshots - # authenticate using kubernetes auth export JWT=$(cat /var/run/secrets/kubernetes/io/serviceaccount/token) export VAULT_TOKEN=$(vault write -field=token auth/kubernetes/login role=$VAULT_ROLE jwt=$JWT) @@ -13,7 +9,7 @@ export VAULT_ADDR=$(vault status -format=yaml | egrep -o '^leader_addr.*' | awk # create snapshot -vault operator raft snapshot save /tmp/vault-snapshots/vault_$(date +%F-%H%M).snapshot +vault operator raft snapshot save /vault-snapshots/vault_$(date +%F-%H%M).snapshot # upload to s3 -s3cmd put /tmp/vault-snapshots/* $S3_URI --host=$S3_HOST --host-bucket=$S3_BUCKET +s3cmd put /vault-snapshots/* $S3_URI --host=$S3_HOST --host-bucket=$S3_BUCKET From dcd21164abea85a8ee40a647bdfc53d829ef0de1 Mon Sep 17 00:00:00 2001 From: Toni Tauro Date: Fri, 2 Jun 2023 10:27:34 +0200 Subject: [PATCH 9/9] Update kubernetes/Dockerfile Co-authored-by: Lukas Grossar --- kubernetes/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/Dockerfile b/kubernetes/Dockerfile index f6df990..fe9856d 100644 --- a/kubernetes/Dockerfile +++ b/kubernetes/Dockerfile @@ -9,4 +9,4 @@ RUN wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VER mv vault /usr/local/bin && rm vault*zip && \ apk add s3cmd && chmod +x entrypoint.sh -ENTRYPOINT /entrypoint.sh +CMD ["/vault-snapshot.sh"]