Skip to content

Migrate persistent volumes to a different storage type

This guide explains how to replace a PersistentVolumeClaim to reference a copy of the original OpenStack volume.

Depending on your application, it may be easier to alternatively delete the PVC & PV, have an empty one provisioned and restore from a backup or if the application is clustered, by streaming from another replica.

Prerequisites

This How-To requires:

  • Access to a MetaKube cluster
  • Access to OpenStack with valid and sufficient credentials
  • No Pod is using the PVC; the OpenStack volume's status must be "available"

Copy volume backing the PV

First, we create a copy of the original OpenStack volume with the new storage type.

  1. Get the OpenStack volume ID backing the PV bound to the PVC
kubectl get pv $(kubectl -n $namespace get pvc $name -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}'
  1. Create a copy of the OpenStack volume

See guide in OpenStack documentation.

Create a modified PV

Now, create a separate PV which is backed by the new volume. It will be pre-bound to a PVC that's created later. That way, the new PVC will not trigger dynamic provisioning.

  1. Get YAML of existing PV
kubectl get pv $(kubectl -n $namespace get pvc $name -o jsonpath='{.spec.volumeName}') -o yaml | tee pv.yml
  1. Overwrite fields

Change fields in pv.yml:

  • metadata.uid: remove
  • metadata.resourceVersion: remove
  • metadata.name: Replace with unique name (for example add -ceph suffix)
  • spec.csi.volumeHandle: Replace with ID of the newly created OpenStack volume
  • spec.claimRef.uid: remove
  • spec.claimRef.resourceVersion: remove

  • Create PV with kubectl

kubectl create -f pv.yml

Replace the PVC

Lastly, replace (delete & create) the PVC. The new one will immediately be bound to the PV we created.

We need to keep the same name, so a Pod referencing the PVC will be able to use it.

  1. Get YAML of existing PVC
kubectl -n $namespace get pvc $name -o yaml | tee pvc.yml
  1. Overwrite fields

Change fields in pvc.yml:

  • metadata.uid: remove
  • metadata.resourceVersion: remove
  • metadata.annotations["pv.kubernetes.io/bind-completed"]: remove
  • spec.storageClassName: Replace with sys11-ceph. This technically doesn't matter, but it would be confusing to leave the old one.
  • spec.volumeName: Replace with name of the new PV

  • Delete PVC

Danger

This will also delete the original PV unless its reclaimPolicy is set to Retain.

kubectl delete -n $namespace $name
  1. Create PVC from manifest
kubectl create -f pvc.yml

Clean up

Once verified that everything worked as expected, you may delete:

  • Original PV & original OpenStack volume (unless already deleted by reclaiming)
  • OpenStack image used in the process to clone the volume