How to make a pvc clone in kubernetes

Sometimes you may need to make a clone of pvc to a namespace that differ from the original one. Here is one method to make a copy of pvc.

Steps

You can use the below steps to clone a pvc in a different namespace

  • Create a PVC in one namespace
  • Make a clone in the same namespace
  • Edit the PV/PVC reclaim policy and change it to Retain
  • Delete the PVC and PVC reference in the PV object.
  • Create the PVC in the different namespace and point to the above PV object.

Usage

Clone pvc from namespace source to dest in kubernetes using the copy.sh script in the last section. You will need to make sure that kubectl is installed.

$ ./copy.sh -o source -c dest -p data-mysql-0

copy.sh

#!/usr/bin/env bash

usage() { echo "$0 usage:" && grep " .)[ ]#" $0; exit 0; }
[ $# -eq 0 ] && usage
while getopts ":ho:c:p:" arg; do
  case $arg in
    o) # The old namespace where pvc will be cloned from.
      old_namespace=${OPTARG}
      ;;
    c) # Current namespace where pvc will be cloned to.
      current_namespace=${OPTARG}
      ;;
    p) # Name of the copied pvc.
      pvc_name=${OPTARG}
      ;;
    h | *) # Display help.
      usage
      exit 0
      ;;
  esac
done

# arguments are all required
if [ -z "$old_namespace" ] || [ -z "$current_namespace" ] || [ -z "$pvc_name" ]; then
    echo "missing -o || -c || -p" >&2
    usage
    exit 1
fi

echo "old: $old_namespace"
echo "new: $current_namespace"

# Make a clone of the pvc.
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ${pvc_name}-clone
  namespace: $old_namespace
spec:
  storageClassName: cbs
  dataSource:
    name: ${pvc_name}
    kind: PersistentVolumeClaim
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
EOF

sleep 10

# set reclainpolicy of the cloned pv to Retain.
export pv=$(kubectl get pvc ${pvc_name}-clone -n $old_namespace -o=jsonpath="{.spec.volumeName}")

kubectl patch pv $pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

# delete the cloned pvc, but retain the cloned pv
kubectl delete pvc ${pvc_name}-clone -n $old_namespace

# unbind the cloned pv
kubectl patch pv $pv --type=json -p="[{'op': 'remove', 'path': '/spec/claimRef'}]"

# create a new pvc binding with the cloned pv.
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ${pvc_name}
  namespace: ${current_namespace}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: cbs
  volumeMode: Filesystem
  volumeName: $pv
EOF
Tags: kubernetes
Share: X (Twitter) Facebook LinkedIn