apiVersion: v1 kind: ConfigMap metadata: name: cephfs-backup-script data: backup.sh: | #!/bin/sh set -eu backup_fs=$(awk '$2 == "/backup" { print $3; exit }' /proc/mounts) source_fs=$(awk '$2 == "/source" { print $3; exit }' /proc/mounts) echo "Backup filesystem: $backup_fs; source filesystem: $source_fs" test "$backup_fs" = bcachefs test "$source_fs" = ceph test -d /source rsync --archive --numeric-ids --inplace --partial --delete --human-readable --stats /source/ /backup/ echo "Completed CephFS mirror for $BACKUP_TARGET" --- apiVersion: batch/v1 kind: CronJob metadata: name: cephfs-backup spec: schedule: "0 3 * * *" timeZone: Europe/Vienna concurrencyPolicy: Forbid startingDeadlineSeconds: 600 successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 7 jobTemplate: spec: backoffLimit: 0 activeDeadlineSeconds: 21600 template: spec: nodeSelector: kubernetes.io/hostname: arschrock tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule automountServiceAccountToken: false restartPolicy: Never securityContext: runAsUser: 0 runAsGroup: 0 containers: - name: rsync image: servercontainers/rsync:a3.24.1-r3.4.1 imagePullPolicy: IfNotPresent command: [/bin/sh, /scripts/backup.sh] env: - name: BACKUP_TARGET value: target securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: [ALL] add: [CHOWN, DAC_OVERRIDE, FOWNER] volumeMounts: - name: backup mountPath: /backup - name: source mountPath: /source readOnly: true - name: scripts mountPath: /scripts readOnly: true volumes: - name: backup hostPath: path: /mnt/backup/kubernetes/cephfs/target type: Directory - name: source persistentVolumeClaim: claimName: target readOnly: true - name: scripts configMap: name: cephfs-backup-script defaultMode: 0555