Skip to main content

Kubernetes Deployment

Run rabbitmq-backup as a Kubernetes CronJob for automated, scheduled backups. Store configuration in a ConfigMap and credentials in a Secret.

Prerequisites

  • A running Kubernetes cluster (1.21+)
  • kubectl configured to access the cluster
  • RabbitMQ accessible from inside the cluster (via Service or external endpoint)
  • Storage backend credentials (S3, Azure Blob, or GCS)

Step 1: Create the Namespace

kubectl create namespace rabbitmq-backup

Step 2: Create a Secret for Credentials

Store sensitive values in a Kubernetes Secret:

secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-backup-credentials
namespace: rabbitmq-backup
type: Opaque
stringData:
RABBITMQ_PASSWORD: "your-rabbitmq-password"
AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
kubectl apply -f secret.yaml
tip

For production, use an external secrets manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) with the External Secrets Operator instead of plain Kubernetes Secrets.

Step 3: Create a ConfigMap for the Backup Config

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: rabbitmq-backup-config
namespace: rabbitmq-backup
data:
backup.yaml: |
mode: backup
backup_id: "k8s-daily-backup"

source:
amqp_url: "amqp://backup_user:${RABBITMQ_PASSWORD}@rabbitmq.default.svc.cluster.local:5672/%2f"
management_url: "http://rabbitmq.default.svc.cluster.local:15672"
management_username: backup_user
management_password: "${RABBITMQ_PASSWORD}"
queues:
include:
- "*"
exclude:
- "*-dead-letter"

storage:
backend: s3
bucket: rabbitmq-backups
region: us-east-1
prefix: k8s-cluster/

backup:
compression: zstd
compression_level: 3
prefetch_count: 100
max_concurrent_queues: 4
include_definitions: true
stop_at_current_depth: true

metrics:
enabled: true
port: 8080
kubectl apply -f configmap.yaml

Step 4: Create the CronJob

cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
spec:
schedule: "0 2 * * *" # Daily at 02:00 UTC
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 3600 # 1 hour timeout
template:
metadata:
labels:
app: rabbitmq-backup
spec:
restartPolicy: OnFailure
containers:
- name: rabbitmq-backup
image: ghcr.io/osodevops/rabbitmq-backup:latest
args:
- backup
- --config
- /config/backup.yaml
envFrom:
- secretRef:
name: rabbitmq-backup-credentials
volumeMounts:
- name: config
mountPath: /config
readOnly: true
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
volumes:
- name: config
configMap:
name: rabbitmq-backup-config
kubectl apply -f cronjob.yaml

Step 5: Verify

Trigger a manual run

kubectl create job --from=cronjob/rabbitmq-backup rabbitmq-backup-manual \
-n rabbitmq-backup

Watch the job

kubectl get jobs -n rabbitmq-backup -w

View logs

kubectl logs -n rabbitmq-backup job/rabbitmq-backup-manual -f

Check CronJob status

kubectl get cronjobs -n rabbitmq-backup

One-Off Restore Job

Create a Job (not CronJob) for restore operations:

restore-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: rabbitmq-restore
namespace: rabbitmq-backup
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: rabbitmq-restore
image: ghcr.io/osodevops/rabbitmq-backup:latest
args:
- restore
- --config
- /config/restore.yaml
envFrom:
- secretRef:
name: rabbitmq-backup-credentials
volumeMounts:
- name: config
mountPath: /config
readOnly: true
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
volumes:
- name: config
configMap:
name: rabbitmq-backup-config

Create the restore config in the same ConfigMap or a separate one, then apply:

kubectl apply -f restore-job.yaml
kubectl logs -n rabbitmq-backup job/rabbitmq-restore -f

Using IAM Roles (IRSA / Workload Identity)

AWS (IRSA)

Annotate the ServiceAccount to assume an IAM role instead of using static credentials:

serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/rabbitmq-backup-role

Reference the ServiceAccount in your CronJob:

spec:
template:
spec:
serviceAccountName: rabbitmq-backup

Remove AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from the Secret -- the AWS SDK picks up credentials from the IRSA token automatically.

GCP (Workload Identity)

apiVersion: v1
kind: ServiceAccount
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
annotations:
iam.gke.io/gcp-service-account: rabbitmq-backup@my-project.iam.gserviceaccount.com

Azure (Workload Identity)

apiVersion: v1
kind: ServiceAccount
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
annotations:
azure.workload.identity/client-id: "your-client-id"
labels:
azure.workload.identity/use: "true"

Monitoring the CronJob

To scrape Prometheus metrics from backup runs, add a port definition and a PodMonitor:

podmonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
spec:
selector:
matchLabels:
app: rabbitmq-backup
podMetricsEndpoints:
- port: metrics
path: /metrics

Add the port to the container spec in the CronJob:

ports:
- name: metrics
containerPort: 8080