Syncing PVCs

Cloning a PVC is simple (though I’ve never done it. That page will be made when needed). However, cloning across namespaces is challenging. Rather than using tar and wormhole in an ungodly combination, it’s reasonably efficient to use rsync.

Create the PVC in the new namespace.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
  namespace: new-ns
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: rook-ceph-nvme-encrypted

Create pods in both the old and new namespaces.

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: temp-pod
  name: temp-pod
spec:
  terminationGracePeriodSeconds: 1
  # If needed due to PVC accessMode
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - topologyKey: kubernetes.io/hostname
          labelSelector:
            matchLabels:
              app.kubernetes.io/name: sample
  containers:
    - command:
        - sleep
        - +Inf
      image: registry.opensuse.org/opensuse/distrobox:latest
      name: opensuse
      volumeMounts:
        - mountPath: /storage
          name: storage
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: pvc

Apply to both namespaces.

Install rsync in the pods if not available. As of 24 Jan 2025, the distrobox image used above includes rsync. If you don’t want to get fancy with heredocs, install vi in the target pod. (The package name is vim-small on openSUSE.)

In the target pod, create a file /etc/rsyncd.conf.

uid = 0
gid = 0
[storage]
path = /storage
read only = false
hosts allow = 10.1.0.0/16

Set the hosts allow parameter to match your pod CIDR.

In the target pod run rsync --daemon --config /etc/rsyncd.conf.

In the source pod run rsync -avz --delete --progress /storage/ rsync://${TARGET_POD_IP}/storage

Enjoy the fruits of your labors.