Recently I have been testing different storage backends (like Rancher Longhorn, Rook, NFS, etc.) for Kubernetes. Since I'm switching pretty frequently, I needed a simple way to migrate or copy data from one pvc to another.
- Make sure both PVCs are created and have PVs associated to them
- Make sure backups are working and current in case the wrong PVC is deleted
- Stop any pods currently using either PVC
- Save the script below as
migrate-pvc.sh
and make it executable - Run the script like
./migrate-pvc.sh old_pvc_id new_pvc_id
(double check what the script does and make sure you put things in the right order, or you'll end up deleting your old/existing pvc) - Watch the logs for the pod created by the new job
- Once the pod completes, check the log for errors/etc
- Delete the old pvc, update deployment specs to point to the new pvc
#!/bin/bash
# See https://justyn.io/til/migrate-kubernetes-pvc-to-another-pvc/ for details
set -exu
src=$1
dst=$2
echo "Creating job yaml"
cat > migrate-job.yaml << EOF
apiVersion: batch/v1
kind: Job
metadata:
name: migrate-pv-$src
spec:
template:
spec:
containers:
- name: migrate
image: debian
command: [ "/bin/bash", "-c" ]
args:
-
apt-get update && apt-get install -y rsync &&
ls -lah /src_vol /dst_vol &&
df -h &&
rsync -avPS --delete /src_vol/ /dst_vol/ &&
ls -lah /dst_vol/ &&
du -shxc /src_vol/ /dst_vol/
volumeMounts:
- mountPath: /src_vol
name: src
readOnly: true
- mountPath: /dst_vol
name: dst
restartPolicy: Never
volumes:
- name: src
persistentVolumeClaim:
claimName: $src
- name: dst
persistentVolumeClaim:
claimName: $dst
backoffLimit: 1
EOF
kubectl create -f migrate-job.yaml
kubectl get jobs -o wide
kubectl get pods | grep migrate
Alternative:
I have not used it, but I stumbled on pv-migrate recently which may be a decent alternative to the above solution. It supports cross-cluster migrations as well.
Another alternative is to use something like Velero to backup one pv and restore it to another.