Claus Gerull

PostgreSQL backup on Kubernetes

Dump all PostgreSql databases with pg_dumpall

Consitent and logical backup of all databases on Postgres, preserving constrains and dependencies.

Kubernetes cronjob

---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: postgresql-pgdumpall
  labels:
    app.kubernetes.io/component: pg_dumpall
spec:
  schedule: "0 23 * * *"
  timeZone: "CET"
  concurrencyPolicy: Allow
  failedJobsHistoryLimit: 1
  successfulJobsHistoryLimit: 3
  startingDeadlineSeconds: 600
  jobTemplate:
    spec:
      ttlSecondsAfterFinished: 86400
      template:
        metadata:
          labels:
            app.kubernetes.io/component: pg_dumpall
          annotations:
            backup.velero.io/backup-volumes: datadir
        spec:
          imagePullSecrets:
            - name: harbor-puller
          containers:
          - name: postgresql-pgdumpall
            image: postgres:17.6-bookworm
            imagePullPolicy: "IfNotPresent"
            env:
              - name: PGUSER
                value: postgres
              - name: PGPASSWORD
                valueFrom:
                  secretKeyRef:
                    name: postgres-users
                    key: postgres-password
              - name: PGHOST
                value: postgresql
              - name: PGPORT
                value: "5432"
              - name: PGDUMP_DIR
                value: /backup/pgdump
            command:
              - /bin/sh
              - -c
              - |
                echo "Starting dump of all PG databases."
                pg_dumpall \
                  --clean \
                  --if-exists \
                  --load-via-partition-root \
                  --quote-all-identifiers \
                  --no-password \
                  --file=${PGDUMP_DIR}/pg_dumpall-$(date '+%Y-%m-%d-%H-%M').sql
                echo "PostgreSql dump finished."
            volumeMounts:
              - name: datadir
                mountPath: /backup/pgdump
                subPath: 
              - name: empty-dir
                mountPath: /tmp
                subPath: tmp-dir
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                - ALL
              privileged: false
              readOnlyRootFilesystem: true
              runAsGroup: 0
              runAsNonRoot: true
              runAsUser: 1001
              seLinuxOptions: {}
              seccompProfile:
                type: RuntimeDefault
            resources:
              limits:
                cpu: 150m
                memory: 192Mi
              requests:
                cpu: 100m
                memory: 128Mi
          restartPolicy: OnFailure
          volumes:
            - name: datadir
              persistentVolumeClaim:
                claimName: postgresql-pgdumpall
            - name: empty-dir
              emptyDir: {}