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 tutorial 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}'
  2. 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
  2. Overwrite fields

    Change fields in pv.yml:

    • metadata.uid: remove
    • metadata.resourceVersion: remove
    • metadata.name: Replace with unique name (e.g. add -ceph suffix)
    • spec.csi.volumeHandle: Replace with ID of the newly created OpenStack volume
    • spec.claimRef.uid: remove
    • spec.claimRef.resourceVersion: remove
  3. 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
  2. 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
  3. Delete PVC

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

    kubectl delete -n $namespace $name
  4. 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