Multi-Cluster Backups¶
The operator can back up PVCs from remote Kubernetes clusters by using an external kubeconfig. The operator runs in one cluster and creates CronJobs that access PVCs in another cluster.
How It Works¶
- You create a kubeconfig Secret containing credentials for the remote cluster
- The VolumeBackup references this kubeconfig in
spec.kubeconfig - The operator uses the external kubeconfig to read PVC/PV information from the remote cluster
- CronJobs are created in the local cluster but mount PVCs from the remote cluster
Create a Kubeconfig Secret¶
apiVersion: v1
kind: Secret
metadata:
name: remote-cluster-kubeconfig
namespace: default
type: Opaque
data:
kubeconfig: <base64-encoded-kubeconfig>
Generate the base64-encoded kubeconfig:
kubectl create secret generic remote-cluster-kubeconfig \
--from-file=kubeconfig=$HOME/.kube/remote-cluster.yaml
VolumeBackup with External Kubeconfig¶
apiVersion: backups.k8s.bnerd.com/v1
kind: VolumeBackup
metadata:
name: remote-backup
namespace: default
spec:
volumeClaimRef:
name: app-data
namespace: production
kubeconfig:
inCluster: false
secretRef:
name: remote-cluster-kubeconfig
namespace: default
key: kubeconfig # Key in the Secret, defaults to "kubeconfig"
schedule: "0 3 * * *"
repository:
type: s3
url: s3:s3.amazonaws.com/my-bucket/remote-backups
secretRef:
name: backup-credentials
Kubeconfig Configuration¶
| Field | Default | Description |
|---|---|---|
kubeconfig.inCluster |
true |
Use in-cluster credentials (set to false for external) |
kubeconfig.secretRef.name |
-- | Secret containing the kubeconfig |
kubeconfig.secretRef.namespace |
-- | Namespace of the kubeconfig Secret |
kubeconfig.secretRef.key |
kubeconfig |
Key in the Secret containing kubeconfig data |
Remote Cluster RBAC¶
The kubeconfig user/ServiceAccount in the remote cluster needs read access to PVCs and PVs:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: backup-operator-reader
rules:
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch"]
Bind this role to the ServiceAccount used in the kubeconfig.
VolumeRestore with External Kubeconfig¶
The same kubeconfig pattern works for VolumeRestore:
apiVersion: backups.k8s.bnerd.com/v1
kind: VolumeRestore
metadata:
name: remote-restore
spec:
kubeconfig:
inCluster: false
secretRef:
name: remote-cluster-kubeconfig
sourceBackup:
volumeBackupRef:
name: remote-backup
targetPVC:
createNew: true
name: "restored-remote-data"
size: "20Gi"
Troubleshooting¶
"unable to connect to API server"
- Verify the kubeconfig is valid:
kubectl --kubeconfig=remote.yaml get nodes - Check that the API server is reachable from the operator pod (firewall, network policies)
- Ensure the kubeconfig uses an endpoint accessible from within the cluster (not
localhost)
"certificate verification failed"
- Ensure the kubeconfig includes the CA certificate or uses
insecure-skip-tls-verify: true(not recommended for production) - If the remote cluster uses a private CA, include it in the kubeconfig's
certificate-authority-data