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)