Kubernetes Operator
Deploy and manage LOX backups in Kubernetes using Custom Resource Definitions (CRDs). GitOps-friendly, auto-scaling, and fully declarative.
Beta Feature
The Kubernetes Operator is currently in beta. APIs may change in future releases. Production use is supported but please report any issues.
Features
- Custom Resource Definitions for declarative backup management
- Automatic backup scheduling with CronJob-like syntax
- PVC and database backup support
- GitOps compatible (ArgoCD, Flux)
- Helm chart for easy deployment
- Prometheus metrics and alerts
Installation
Using Helm
# Add the LOX Helm repository
helm repo add lox https://charts.backlox.com
helm repo update
# Install the operator
helm install lox-operator lox/lox-operator \
--namespace lox-system \
--create-namespace \
--set apiKey=${LOX_API_KEY}Using kubectl
# Install CRDs
kubectl apply -f https://raw.githubusercontent.com/loxbackup/operator/main/config/crd/bases/backlox.com_backups.yaml
kubectl apply -f https://raw.githubusercontent.com/loxbackup/operator/main/config/crd/bases/backlox.com_backupschedules.yaml
# Create namespace and secret
kubectl create namespace lox-system
kubectl create secret generic lox-credentials \
--namespace lox-system \
--from-literal=api-key=${LOX_API_KEY}
# Deploy operator
kubectl apply -f https://raw.githubusercontent.com/loxbackup/operator/main/config/deploy/operator.yamlCustom Resources
Backup
The Backup resource triggers a one-time backup.
apiVersion: backlox.com/v1alpha1
kind: Backup
metadata:
name: my-app-backup
namespace: default
spec:
# Backup a PVC
source:
type: pvc
pvcName: my-app-data
# Optional: specific paths within the PVC
paths:
- /data
- /config
# Backup configuration
retention:
days: 30
tags:
- kubernetes
- my-app
- production
# Optional: run pre/post backup hooks
hooks:
pre:
- exec:
container: my-app
command: ["/bin/sh", "-c", "pg_dump > /backup/db.sql"]
post:
- exec:
container: my-app
command: ["/bin/sh", "-c", "rm /backup/db.sql"]BackupSchedule
The BackupSchedule resource creates recurring backups.
apiVersion: backlox.com/v1alpha1
kind: BackupSchedule
metadata:
name: nightly-backup
namespace: default
spec:
# Cron schedule (UTC)
schedule: "0 2 * * *"
# Backup template
template:
spec:
source:
type: pvc
pvcName: my-app-data
retention:
days: 7
keepLast: 5
tags:
- scheduled
- nightly
# Keep last N successful backups
successfulBackupsHistoryLimit: 5
failedBackupsHistoryLimit: 3DatabaseBackup
The DatabaseBackup resource backs up databases running in Kubernetes.
apiVersion: backlox.com/v1alpha1
kind: DatabaseBackup
metadata:
name: postgres-backup
namespace: default
spec:
# Database type
type: postgresql
# Connection details (from secret)
connectionSecret:
name: postgres-credentials
keys:
host: PGHOST
port: PGPORT
user: PGUSER
password: PGPASSWORD
database: PGDATABASE
# Or reference a Kubernetes service
service:
name: postgres
port: 5432
# Backup options
options:
format: custom # plain, custom, tar
compress: 9
retention:
days: 30
tags:
- postgresql
- productionExamples
WordPress with MySQL
---
apiVersion: backlox.com/v1alpha1
kind: BackupSchedule
metadata:
name: wordpress-files
spec:
schedule: "0 3 * * *"
template:
spec:
source:
type: pvc
pvcName: wordpress-data
paths:
- /var/www/html/wp-content
retention:
days: 30
tags: [wordpress, files]
---
apiVersion: backlox.com/v1alpha1
kind: DatabaseBackup
metadata:
name: wordpress-db
spec:
type: mysql
schedule: "0 3 * * *"
connectionSecret:
name: wordpress-mysql
retention:
days: 30
tags: [wordpress, mysql]MongoDB Replica Set
apiVersion: backlox.com/v1alpha1
kind: DatabaseBackup
metadata:
name: mongodb-backup
spec:
type: mongodb
schedule: "0 */6 * * *" # Every 6 hours
# Connection URI from secret
connectionSecret:
name: mongodb-credentials
keys:
uri: MONGODB_URI
options:
oplog: true # For point-in-time recovery
gzip: true
parallelCollections: 4
retention:
days: 14
keepLast: 10
tags:
- mongodb
- replica-setMonitoring
Prometheus Metrics
The operator exposes metrics on :8080/metrics:
# Backup metrics
lox_backup_total{status="success", namespace="default"}
lox_backup_total{status="failed", namespace="default"}
lox_backup_duration_seconds{namespace="default", name="my-backup"}
lox_backup_size_bytes{namespace="default", name="my-backup"}
# Schedule metrics
lox_schedule_last_backup_time{namespace="default", name="nightly"}
lox_schedule_next_backup_time{namespace="default", name="nightly"}
# Operator health
lox_operator_reconcile_total
lox_operator_reconcile_errors_totalAlerting Rules
groups:
- name: lox-backup
rules:
- alert: BackupFailed
expr: increase(lox_backup_total{status="failed"}[1h]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "LOX backup failed"
description: "Backup {{ $labels.name }} in {{ $labels.namespace }} failed"
- alert: BackupMissing
expr: time() - lox_schedule_last_backup_time > 86400 * 2
for: 1h
labels:
severity: warning
annotations:
summary: "LOX backup schedule missed"
description: "No backup for {{ $labels.name }} in last 48 hours"Status
Backup Status
$ kubectl get backups NAME STATUS SIZE AGE my-app-backup Completed 1.2 GB 5m db-backup InProgress - 1m old-backup Failed - 1h
Describe Backup
$ kubectl describe backup my-app-backup Name: my-app-backup Namespace: default Status: Phase: Completed UUID: abc123-def456-... Size: 1288490188 Started At: 2025-12-25T03:00:00Z Completed At: 2025-12-25T03:05:32Z Checksum: sha256:abc123... Events: Type Reason Age Message ---- ------ ---- ------- Normal Started 6m Backup started Normal Uploaded 3m Backup uploaded to LOX Normal Verified 1m Backup verified and distributed
Troubleshooting
Backup stuck in InProgress
Check the operator logs: kubectl logs -n lox-system deploy/lox-operator. Common causes: PVC not accessible, insufficient permissions.
CRDs not found
Ensure CRDs are installed: kubectl get crd | grep backlox.com. Re-install with helm upgrade --install.
Debug mode
Enable debug logging: helm upgrade lox-operator lox/lox-operator --set logLevel=debug
RBAC Requirements
The operator requires the following permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: lox-operator
rules:
- apiGroups: ["backlox.com"]
resources: ["backups", "backupschedules", "databasebackups"]
verbs: ["*"]
- apiGroups: [""]
resources: ["pods", "persistentvolumeclaims", "secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["*"]