Kubernetes operator · karkive.io/v1alpha1

You declare a Backup.
KArkive runs the archive.

Scheduled logical backups and restores, in-cluster. A CR becomes a ConfigMap, optional PVC, and CronJob that dump, gzip, GPG-encrypt, and sync to S3 — and the reverse on restore.

install
helm install karkive oci://ghcr.io/mahdidarabi/charts/karkive \
  --version 0.0.10-p.5 \
  -n karkive-system --create-namespace

How it works

A CR. Owned jobs. A pipeline you can read.

The operator never shells out from the controller. It admits resources, then a Job runs the stages — one container each, in order.

  1. CR Backup / Restore
  2. Op KArkive reconciles
  3. Own ConfigMap · PVC · CronJob
  4. Job Pipeline pod

Backup

  1. cleanup
  2. dump
  3. compress
  4. encrypt
  5. s3-sync

Skip s3-sync when spec.s3.enabled is false; encrypted dumps stay on the PVC.

Restore

  1. cleanup
  2. fetch
  3. decrypt
  4. extract
  5. restore

Target credentials come from an engine secret, not from the S3/GPG secretRef.

API

Write YAML you already know.

Backup and Restore are namespaced CRs. Short names: kbackup / bak, krestore / res.

  • Secrets stay yours. The operator never creates or mutates them. It only reads spec.secretRef (and the engine restore secret) in the CR namespace.
  • Names are kind-prefixed. Owned objects are karkive-backup-<name> and karkive-restore-<name>, so both CRs can share a name.
  • Ready is not last-job. status.phase is admission of owned resources. Last Job outcome is BackupSucceeded / RestoreSucceeded.
backup.yaml
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

Three logical dumps. One CR shape.

PostgreSQL

pg_dump in, pgrestore out. Defaults to CloudNativePG PostgreSQL 18.4. Optional pgAudit DDL strip on restore.

MariaDB

mysqldump with utf8mb4 / hex-blob. Restore recreates the schema and strips GTID/DEFINER noise.

Redis

redis-cli --rdb on backup. Restore loads an ephemeral redis-server and REPLICAOF into the target.

In production

Webhooks, metrics, Helm — not a sidecar script.

Observability

Know the state of every archive.

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.

Dashboards / KArkive Backup & restore overview
All namespaces All engines Last 24 hours
Backups ready 12 / 12 ● synced
Restores ready 3 / 3 ● synced
Last job failed 0 ● healthy
Stale backups 0 ● within policy
Suspended 2 ● paused by spec
Last job durationseconds
00:0012:00now
BackupRestoremax 74s
Time since last successhours
00:0012:00now
Oldest success36h stale alert18h 24m
Last joblive from Prometheus
Kind / NameEngineOutcomeDurationSuccess age
Backup · app-postgrespostgresSucceeded42s2h 14m
Backup · cache-redisredisSucceeded8s5h 02m
Restore · staging-dbmariadbSucceeded61s19h 41m

Included alert coverage: not Ready, failed Job, aging or stale Backup, no finished Job, and missed CronJob schedule.

View dashboard JSON ↗

Grafana setup

Connect the dashboard in three steps.

  1. 01 Scrape KArkive

    Use the Prometheus Operator integration or scrape the metrics Service at /metrics on port 8080.

  2. 02 Add the dashboard

    Enable the Grafana sidecar, or import karkive.json manually and select your Prometheus datasource.

  3. 03 Keep the filters

    The dashboard uses $namespace, $engine, and a 30s refresh to follow every CR.

Helm switches: metrics.serviceMonitor.enabled=true metrics.grafanaDashboard.enabled=true Default dashboard label: grafana_dashboard: "1".

Install

Helm from GHCR.

Current chart: 0.0.10-p.5. Images publish to ghcr.io/mahdidarabi/karkive; charts to oci://ghcr.io/mahdidarabi/charts/karkive.

helm
helm install karkive oci://ghcr.io/mahdidarabi/charts/karkive \
  --version 0.0.10-p.5 \
  -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.

01

Before you start

  • Helm 3 with OCI registry support
  • A kubeconfig with permission to install CRDs
  • Existing cert-manager only when webhook certificates use it
  • Prometheus Operator is optional for ServiceMonitor and alerts
02

Enable observability

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
03

Verify and declare

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.