Backup
- cleanup
- dump
- compress
- encrypt
- s3-sync
Skip s3-sync when spec.s3.enabled is false; encrypted dumps stay on the PVC. For engine: pvc, dump is tar of the source claim.
Kubernetes operator · karkive.io/v1alpha1
Scheduled logical backups and restores, in-cluster. A CR becomes a ConfigMap, optional PVC, and CronJob that dump (or tar a PVC), gzip, GPG-encrypt, and sync to S3 — and the reverse on restore.
helm install karkive oci://ghcr.io/mahdidarabi/charts/karkive \
--version 0.0.13 \
-n karkive-system --create-namespace
How it works
The operator never shells out from the controller. It admits resources, then a Job runs the stages — one container each, in order.
Skip s3-sync when spec.s3.enabled is false; encrypted dumps stay on the PVC. For engine: pvc, dump is tar of the source claim.
Target credentials come from an engine secret, not from the S3/GPG secretRef.
API
Backup and Restore are namespaced CRs. Short names:
kbackup / bak, krestore / res.
spec.secretRef (and the engine restore secret) in the CR namespace.
karkive-backup-<name> and
karkive-restore-<name>, so both CRs can share a name.
status.phase is admission of owned resources.
Last Job outcome is BackupSucceeded / RestoreSucceeded.
apiVersion: karkive.io/v1alpha1
kind: Backup
metadata:
name: app-postgres
spec:
engine: postgres
schedule: "0 2 * * *"
database:
host: postgres.example.svc
name: app
s3:
endpoint: https://s3.example.com
bucket: backups
path: app/pgdump
secretRef:
name: backup-app-postgres
Engines
pg_dump in, pgrestore out. Defaults to CloudNativePG PostgreSQL 18.4. Optional pgAudit extension and event-trigger strip on restore.
mysqldump with utf8mb4 / hex-blob. Restore recreates the schema and strips GTID/DEFINER noise.
redis-cli --rdb on backup. Restore loads an ephemeral redis-server and REPLICAOF into the target.
GNU tar of an existing claim, mounted read-only. consumerSelector lands the Job on the app's node for RWO claims. Backup only.
In production
Reject bad cron, missing engine secrets, and incomplete specs before they land.
Per-CR ready/suspend, last success, last-job failure and duration. Optional ServiceMonitor, PrometheusRule, dashboard ConfigMap.
S3 object retention and local encrypted dumps on the PVC. Persistence can be swapped for emptyDir.
Keep the CronJob, suspend the schedule, then kubectl create job --from=… when you mean it.
Observability
KArkive exposes Prometheus metrics per namespace, name, and engine. The Helm chart can install a ServiceMonitor, alert rules, and this ready-to-import Grafana dashboard. One Prometheus for several clusters? Name the label that tells them apart and the dashboard keeps them apart too.
Included alert coverage: not Ready, failed Job, aging or stale Backup, no finished Job, and missed CronJob schedule.
View dashboard JSON ↗Grafana setup
Use the Prometheus Operator integration or scrape the metrics Service at /metrics on port 8080.
Enable the Grafana sidecar, or import karkive.json manually and select your Prometheus datasource.
The dashboard uses $namespace, $engine, and a 30s refresh to follow every CR. Set sourceLabel to add a $source filter for many clusters in one Prometheus.
Helm switches:
metrics.serviceMonitor.enabled=true
metrics.grafanaDashboard.enabled=true
metrics.grafanaDashboard.sourceLabel=cluster
Default dashboard label: grafana_dashboard: "1". sourceLabel is empty by default; set it to your cluster label (cluster, k8s_cluster, …).
Install
Current chart: 0.0.13.
Images publish to ghcr.io/mahdidarabi/karkive; charts to
oci://ghcr.io/mahdidarabi/charts/karkive.
helm install karkive oci://ghcr.io/mahdidarabi/charts/karkive \
--version 0.0.13 \
-n karkive-system --create-namespace
Add --set metrics.serviceMonitor.enabled=true (and PrometheusRule / Grafana dashboard)
when you already run kube-prometheus. On GitOps, set
webhook.certManager.enabled=true so Helm does not regenerate the webhook CA every template.
Full knobs live in the
README.
Turn on the integrations when kube-prometheus is already installed:
helm upgrade --install karkive \
oci://ghcr.io/mahdidarabi/charts/karkive \
-n karkive-system --create-namespace \
--set metrics.serviceMonitor.enabled=true \
--set metrics.prometheusRule.enabled=true \
--set metrics.grafanaDashboard.enabled=true
kubectl get deploy,svc -n karkive-system
kubectl get crd backups.karkive.io \
restores.karkive.io
# Then apply a Secret and a Backup CR
kubectl apply -f config/samples/backup-secret.yaml
kubectl apply -f config/samples/karkive_v1alpha1_backup.yaml
Update the sample endpoint and credentials before applying it to a real cluster.