Created
May 13, 2024 00:49
-
-
Save pschichtel/578822f83535172230e315fd9ced2bd5 to your computer and use it in GitHub Desktop.
A small script to migrate PVCs and their data to a new storage class. It requires bash, kubectl, yq, jq and [pv-migrate](https://github.com/utkuozdemir/pv-migrate).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
namespace="${1?no namespace}" | |
source_pvc="${2?no source pvc}" | |
target_sc="${3?no target SC}" | |
tmp_pvc_name="${source_pvc}-tmp" | |
echo "Exporting the current PVC..." | |
manifest="$(mktemp --suffix=.yaml)" | |
kubectl -n "$namespace" get pvc "$source_pvc" -o yaml > "$manifest" | |
echo "Deriving template for new temporary PVC..." | |
# cleanup stuff | |
yq eval -i 'del(.metadata.annotations) | del(.metadata.creationTimestamp) | del(.metadata.finalizers) | del(.metadata.uid) | del(.status) | del(.metadata.resourceVersion) | del(.spec.volumeName) ' "$manifest" | |
# patch the SC name and pvc-name | |
SC_NAME="$target_sc" PVC_NAME="$tmp_pvc_name" yq eval -i '.spec.storageClassName = env(SC_NAME) | .metadata.name = env(PVC_NAME)' "$manifest" | |
if [ -n "${PVC_OVERRIDE_SIZE:-}" ] | |
then | |
yq eval -i '.spec.resources.requests.storage = env(PVC_OVERRIDE_SIZE)' "$manifest" | |
fi | |
echo "Creating temporary new PVC for data migration..." | |
kubectl -n "$namespace" create -f "$manifest" | |
echo "Migrating the data from the old to the temporary PVC..." | |
pv-migrate migrate \ | |
--source-namespace "$namespace" \ | |
--dest-namespace "$namespace" \ | |
"$source_pvc" \ | |
"$tmp_pvc_name" | |
pv="$(kubectl -n "$namespace" get pvc "$tmp_pvc_name" -o json | jq -r .spec.volumeName)" | |
reclaimPolicy="$(kubectl get pv "$pv" -o json | jq -r .spec.persistentVolumeReclaimPolicy)" | |
if [ "$reclaimPolicy" != "Retain" ] | |
then | |
echo "Switch the new PV's reclaim policy to Retain for the PVC swap..." | |
kubectl patch pv "$pv" -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' | |
fi | |
echo "Deleting the current PVCs..." | |
kubectl -n "$namespace" delete pvc "$source_pvc" "$tmp_pvc_name" | |
echo "Creating the final PVC with the old name..." | |
PV="$pv" PVC_NAME="$source_pvc" yq eval -i '.metadata.name = env(PVC_NAME) | .spec.volumeName = env(PV)' "$manifest" | |
kubectl -n "$namespace" create -f "$manifest" | |
echo "Patching the PV to reference the final PVC..." | |
claim_ref_patch="$(kubectl -n "$namespace" get pvc "$source_pvc" -o json | jq -c '{spec: {claimRef: {apiVersion: .apiVersion, kind: .kind, name: .metadata.name, namespace: .metadata.namespace, resourceVersion: .metadata.resourceVersion, uid: .metadata.uid}}}')" | |
kubectl patch pv "$pv" -p "$claim_ref_patch" | |
if [ "$reclaimPolicy" != "Retain" ] | |
then | |
echo "Reset the PV's reclaim policy to its original value..." | |
kubectl patch pv "$pv" -p '{"spec":{"persistentVolumeReclaimPolicy":"'"$reclaimPolicy"'"}}' | |
fi | |
echo "Done!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment