Examples
A Postgres in the cluster, backed up from the manifest that deploys it.
View as MarkdownEverything here uses the Deployment that works today. When the
operator ships, the config.yaml in these examples is unchanged; only what owns the pod
changes.
A Postgres in the cluster
The worker reaches an in-cluster database the way any other pod does, by service DNS. The
backup ID is the one from the dashboard or sctl backup list.
api_url: https://api.saved.sh
token: "<shown once when the worker was provisioned>"
local_temp_path: /var/lib/saved
backups:
"018f3c2a-9d41-7c33-b2e1-5a0c7f9e1b44":
source_type: postgres
compression: true
encryption:
public_key: ./prod.asc
source:
host: postgres.default.svc.cluster.local
port: 5432
database: app
user: backup
password: "<password>"
ssl_mode: require
exclude_tables: [audit_log, sessions]The encryption key in the same Secret
public_key takes a path relative to the config file's own directory, and the config file
lives in the Secret mount. Put the armoured key in the same Secret and it resolves without
any extra volume.
gpg --armor --export backups@example.com > prod.asc
kubectl -n saved create secret generic saved-worker-config \
--from-file=config.yaml=./config.yaml \
--from-file=prod.asc=./prod.ascWith the Secret mounted at /etc/saved and workingDir: /etc/saved, ./prod.asc is
/etc/saved/prod.asc. We hold only the public half, and we cannot recover a backup if you
lose the private one. See Encryption.
A script source against an in-cluster service
A script source runs a command inside the worker container, so it can only use what that
image has: curl, pg_dump and mysqldump. Ship the script itself in a
ConfigMap and mount it executable.
backups:
"018f8c5f-3e46-7da8-a071-5f1c6d4e8a35":
source_type: script
source:
path: /opt/saved/export.sh
interpreter: /bin/sh volumeMounts:
- name: scripts
mountPath: /opt/saved
readOnly: true
volumes:
- name: scripts
configMap:
name: saved-scripts
defaultMode: 0555#!/bin/sh
set -eu
curl -fsS http://reports.default.svc.cluster.local/export > "$SAVED_OUTPUT"Setting interpreter means the file does not have to be executable, which saves an argument
about ConfigMap file modes. Write to $SAVED_OUTPUT: anything on stdout is treated as a
log, not as backup data.
Backing up a PersistentVolumeClaim
Use a folder source and mount the claim into the worker.
volumeMounts:
- name: uploads
mountPath: /data/uploads
readOnly: true
volumes:
- name: uploads
persistentVolumeClaim:
claimName: app-uploads
readOnly: truebackups:
"018f7b4e-2d35-7c97-9f60-4e0b5c3d7f24":
source_type: folder
compression: true
source:
path: /data/uploads
exclude: ["*.tmp", "cache"]A ReadWriteOnce claim can only be mounted by pods on one node. If the application already
holds it, the worker pod will not schedule until it is on that node too, or the claim
supports ReadWriteMany. This is a property of the volume, not of the worker.
The result is one zip of the tree, encrypted before it leaves the cluster. Entries are stored without zip compression, because the encrypt step compresses anyway.