Difference between revisions of "Pvc migration testing"
Jump to navigation
Jump to search
(Created page with "# 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:-d...") |
|||
Line 61: | Line 61: | ||
SRC_SC="${2:?Source storage class required}" | SRC_SC="${2:?Source storage class required}" | ||
DEST_SC="${3:?Destination 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 | if [[ -z "$pvcs" ]]; then | ||
− | echo "No PVCs found | + | echo "No matching PVCs found" |
exit 0 | exit 0 | ||
fi | fi | ||
Line 74: | Line 91: | ||
tmp_pvc="${pvc}-tmp" | tmp_pvc="${pvc}-tmp" | ||
− | echo "🔷 Scaling down | + | echo "🔷 Scaling down workloads using PVC $pvc..." |
− | + | scaled_objects=() | |
− | for | + | for obj in $(kubectl get deploy,sts -n "$NS" -o name); do |
− | if kubectl get "$ | + | if kubectl get "$obj" -n "$NS" -o json | grep -q "$pvc"; then |
− | echo "Scaling $ | + | echo "Scaling $obj to 0" |
− | kubectl scale "$ | + | kubectl scale "$obj" -n "$NS" --replicas=0 |
− | + | scaled_objects+=("$obj") | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
fi | fi | ||
done | done | ||
Line 110: | Line 121: | ||
--dest "$tmp_pvc" \ | --dest "$tmp_pvc" \ | ||
-N "$NS" \ | -N "$NS" \ | ||
+ | --strategies mnt2,svc \ | ||
--compress \ | --compress \ | ||
--ignore-mounted | --ignore-mounted | ||
Line 142: | Line 154: | ||
kubectl delete pvc "$tmp_pvc" -n "$NS" | kubectl delete pvc "$tmp_pvc" -n "$NS" | ||
− | echo "🔷 Scaling up | + | echo "🔷 Scaling workloads back up..." |
− | for | + | for obj in "${scaled_objects[@]}"; do |
− | + | echo "Scaling $obj to 1" | |
− | + | kubectl scale "$obj" -n "$NS" --replicas=1 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
done | done | ||
echo "✅ Migration of PVC $pvc complete." | echo "✅ Migration of PVC $pvc complete." | ||
done | done | ||
+ | ``` | ||
+ | |||
+ | ### example | ||
+ | ``` | ||
+ | ./swap-storage-class.sh prometheus managed-csi-hdd standardssd-zrs prometheus-server | ||
``` | ``` | ||
Latest revision as of 23:23, 23 July 2025
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)