Pvc migration testing
Jump to navigation
Jump to search
Migrate many PVCs from one storage class to another in same namespace
Use these scripts for migration and testing
create-test-pvc.sh
#!/bin/bash set -eu NS=${1:-default} SC=${2:-managed-csi-hdd} PVC_NAME=test-pvc POD_NAME=test-pod cat <<EOF | kubectl apply -n $NS -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: $PVC_NAME spec: accessModes: [ReadWriteOnce] resources: requests: storage: 1Gi EOF cat <<EOF | kubectl apply -n $NS -f - apiVersion: v1 kind: Pod metadata: name: $POD_NAME spec: containers: - name: busybox image: busybox command: ["sleep", "3600"] volumeMounts: - name: vol mountPath: /data volumes: - name: vol persistentVolumeClaim: claimName: $PVC_NAME EOF kubectl wait --for=condition=Ready pod/$POD_NAME -n $NS --timeout=60s kubectl exec -n $NS $POD_NAME -- sh -c 'echo "This is a test." > /data/test.txt' # kubectl delete pod/$POD_NAME pvc/$PVC_NAME -n $NS kubectl delete pod/$POD_NAME -n $NS
swap-storage-class.sh
#!/bin/bash set -euo pipefail NS="${1:?Namespace required}" SRC_SC="${2:?Source storage class required}" DEST_SC="${3:?Destination storage class required}" SINGLE_PVC="${4:-}" # optional fourth arg get_matching_pvcs() { if [[ -n "$SINGLE_PVC" ]]; then size=$(kubectl get pvc "$SINGLE_PVC" -n "$NS" -o jsonpath='{.spec.resources.requests.storage}') sc=$(kubectl get pvc "$SINGLE_PVC" -n "$NS" -o jsonpath='{.spec.storageClassName}') if [[ "$sc" == "$SRC_SC" ]]; then echo "$SINGLE_PVC|$size" else echo "❌ PVC '$SINGLE_PVC' does not use storageClass '$SRC_SC'" >&2 exit 1 fi else kubectl get pvc -n "$NS" -o jsonpath='{range .items[*]}{.metadata.name}{"|"}{.spec.storageClassName}{"|"}{.spec.resources.requests.storage}{"\n"}{end}' | awk -F'|' -v sc="$SRC_SC" '$2==sc{print $1 "|" $3}' fi } pvcs=$(get_matching_pvcs) if [[ -z "$pvcs" ]]; then echo "No matching PVCs found" exit 0 fi for line in $pvcs; do pvc=$(cut -d'|' -f1 <<<"$line") size=$(cut -d'|' -f2 <<<"$line") tmp_pvc="${pvc}-tmp" echo "🔷 Scaling down workloads using PVC $pvc..." scaled_objects=() for obj in $(kubectl get deploy,sts -n "$NS" -o name); do if kubectl get "$obj" -n "$NS" -o json | grep -q "$pvc"; then echo "Scaling $obj to 0" kubectl scale "$obj" -n "$NS" --replicas=0 scaled_objects+=("$obj") fi done echo "🔷 Creating temporary PVC $tmp_pvc with $DEST_SC..." cat <<EOF | kubectl apply -n "$NS" -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: $tmp_pvc spec: accessModes: [ReadWriteOnce] resources: requests: storage: $size storageClassName: $DEST_SC EOF echo "🔷 Migrating data from $pvc -> $tmp_pvc..." pv-migrate \ --source "$pvc" \ -n "$NS" \ --dest "$tmp_pvc" \ -N "$NS" \ --strategies mnt2,svc \ --compress \ --ignore-mounted echo "🔷 Deleting original PVC $pvc..." kubectl delete pvc "$pvc" -n "$NS" echo "🔷 Re-creating original PVC $pvc with $DEST_SC..." cat <<EOF | kubectl apply -n "$NS" -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: $pvc spec: accessModes: [ReadWriteOnce] resources: requests: storage: $size storageClassName: $DEST_SC EOF echo "🔷 Migrating data back from $tmp_pvc -> $pvc..." pv-migrate \ --source "$tmp_pvc" \ -n "$NS" \ --dest "$pvc" \ -N "$NS" \ --compress \ --ignore-mounted echo "🔷 Deleting temporary PVC $tmp_pvc..." kubectl delete pvc "$tmp_pvc" -n "$NS" echo "🔷 Scaling workloads back up..." for obj in "${scaled_objects[@]}"; do echo "Scaling $obj to 1" kubectl scale "$obj" -n "$NS" --replicas=1 done echo "✅ Migration of PVC $pvc complete." done
example
./swap-storage-class.sh prometheus managed-csi-hdd standardssd-zrs prometheus-server
create-test-pod-and-mount.yaml
apiVersion: v1 kind: Pod metadata: name: ubuntu-pvc-pod spec: volumes: - name: my-pvc-storage persistentVolumeClaim: claimName: test-pvc # Replace with the name of your existing PVC containers: - name: ubuntu-container image: ubuntu:latest command: ["sleep", "infinity"] volumeMounts: - name: my-pvc-storage mountPath: /data # Replace with the desired mount path inside the container (e.g., /mnt/data)