pv-migrate is a CLI tool/kubectl plugin to easily migrate
the contents of one Kubernetes PersistentVolume[Claim] to another.
On Kubernetes, if you need to rename a resource (like a Deployment) or to move it to a different namespace,
you can simply create a copy of its manifest with the new namespace and/or name and apply it.
However, it is not as simple with PersistentVolumeClaim resources: They are not only metadata,
but they also store data in the underlying storage backend.
In these cases, moving the data stored in the PVC can become a problem, making migrations more difficult.
-
Case 1: You have a database that has a PersistentVolumeClaim
db-dataof size50Gi. Time shows that50Giwas not enough, and it filled all the disk space.
And unfortunately, your StorageClass/provisioner doesn't support volume expansion. Now you need to create a new PVC of1Tiand somehow copy all the data to the new volume, as-is, with its file ownership and permissions.
Simply create the new PVCdb-data-v2, and usepv-migrateto move data fromdb-datatodb-data-v2. -
Case 2: You need to move PersistentVolumeClaim
my-pvcfrom namespacens-ato namespacens-b.
Simply create the PVC with the same name and manifest inns-band usepv-migrateto clone its content. -
Case 3: You are moving from one cloud provider to another! Now you need to move the database from one Kubernetes cluster to the other.
Both clusters have internet access and the source cluster supportsLoadBalancertype services with public IPs.
Just usepv-migrateto clone the data securely over the internet.
- Supports in-namespace, in-cluster as well as cross-cluster migrations
- Uses rsync over SSH with a freshly generated Ed25519 or RSA keys each time to securely migrate the files
- Allows specifying your own docker images for rsync and sshd
- Supports multiple migration strategies to do the migration efficiently and fallback to other strategies when needed
- Customizable strategy order
- Supports arm32v7 (Raspberry Pi etc.) and arm64 architectures as well as amd64
If you have homebrew, the installation is as simple as:
brew tap utkuozdemir/pv-migrate
brew install pv-migrateIf you use Scoop package manager on Windows, run the following commands in a command prompt (CMD/Powershell):
scoop bucket add pv-migrate https://github.com/utkuozdemir/scoop-pv-migrate.git
scoop install pv-migrate/pv-migrate- Go to the releases and download the latest release archive for your platform.
- Extract the archive.
- Move the binary to somewhere in your
PATH.
Sample steps for MacOS:
$ VERSION=0.6.0
$ wget https://github.com/utkuozdemir/pv-migrate/releases/download/v${VERSION}/pv-migrate_${VERSION}_darwin_x86_64.tar.gz
$ tar -xvzf pv-migrate_${VERSION}_darwin_x86_64.tar.gz
$ mv pv-migrate /usr/local/bin
$ pv-migrate --helpAlternatively, you can use the
official Docker images
that come with the pv-migrate binary pre-installed:
docker run --rm -it utkuozdemir/pv-migrate:0.6.0 pv-migrate migrate ...Main command:
NAME:
pv-migrate - A command-line utility to migrate data from one Kubernetes PersistentVolumeClaim to another
USAGE:
pv-migrate [global options] command [command options] [arguments...]
COMMANDS:
migrate, m Migrate data from the source pvc to the destination pvc
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help (default: false)
--version, -v print the version (default: false)
--log-level value, -l value Log level. Must be one of: trace, debug, info, warn, error, fatal, panic (default: "info")
--log-format value, -f value Log format. Must be one of: json, fancy (default: "fancy")
Command migrate:
NAME:
pv-migrate migrate - Migrate data from the source PVC to the destination PVC
USAGE:
pv-migrate migrate [command options] [SOURCE_PVC] [DESTINATION_PVC]
OPTIONS:
--source-kubeconfig value, -k value Path of the kubeconfig file of the source PVC (default: ~/.kube/config or KUBECONFIG env variable)
--source-context value, -c value Context in the kubeconfig file of the source PVC (default: currently selected context in the source kubeconfig)
--source-namespace value, -n value Namespace of the source PVC (default: currently selected namespace in the source context)
--source-path value, -p value The filesystem path to migrate in the the source PVC (default: "/")
--source-mount-read-only, -R Mount the source PVC in ReadOnly mode (default: true)
--dest-kubeconfig value, -K value Path of the kubeconfig file of the destination PVC (default: ~/.kube/config or KUBECONFIG env variable)
--dest-context value, -C value Context in the kubeconfig file of the destination PVC (default: currently selected context in the destination kubeconfig)
--dest-namespace value, -N value Namespace of the destination PVC (default: currently selected namespace in the destination context)
--dest-path value, -P value The filesystem path to migrate in the the dest PVC (default: "/")
--dest-delete-extraneous-files, -d Delete extraneous files on the destination by using rsync's '--delete' flag (default: false)
--ignore-mounted, -i Do not fail if the source or destination PVC is mounted (default: false)
--no-chown, -o Omit chown on rsync (default: false)
--no-progress-bar, -b Do not display a progress bar (default: false)
--strategies value, -s value The strategies to be used in the given order (default: "mnt2", "svc", "lbsvc")
--rsync-image value, -r value Image to use for running rsync (default: "docker.io/utkuozdemir/pv-migrate-rsync:1.0.0")
--rsync-service-account value Service account for the rsync pod (default: "default")
--sshd-image value, -S value Image to use for running sshd server (default: "docker.io/utkuozdemir/pv-migrate-sshd:1.0.0")
--sshd-service-account value Service account for the sshd pod (default: "default")
--ssh-key-algorithm value, -a value SSH key algorithm to be used. Valid values are rsa,ed25519 (default: "ed25519")
--help, -h show help (default: false)
pv-migrate has multiple strategies implemented to carry out the migration operation. Those are the following:
| Name | Description |
|---|---|
mnt2 |
Mount both - Mounts both PVCs in a single pod and runs a regular rsync, without using SSH or the network. Only applicable if source and destination PVCs are in the same namespace and both can be mounted from a single pod. |
svc |
Service - Runs rsync+ssh over a Kubernetes Service (ClusterIP). Only applicable when source and destination PVCs are in the same Kubernetes cluster. |
lbsvc |
Load Balancer Service - Runs rsync+ssh over a Kubernetes Service of type LoadBalancer. Always applicable (will fail if LoadBalancer IP is not assigned for a long period). |
To migrate contents of PersistentVolumeClaim small-pvc in namespace source-ns
to the PersistentVolumeClaim big-pvc in namespace dest-ns, use the following command:
$ pv-migrate migrate \
--source-namespace source-ns \
--dest-namespace dest-ns \
small-pvc big-pvcFull example between different clusters:
pv-migrate migrate \
--source-kubeconfig /path/to/source/kubeconfig \
--source-context some-context \
--source-namespace source-ns \
--dest-kubeconfig /path/to/dest/kubeconfig \
--dest-context some-other-context \
--dest-namespace dest-ns \
--dest-delete-extraneous-files \
old-pvc new-pvcNote: For it to run as kubectl plugin via kubectl pv-migrate ...,
put the binary with name kubectl-pv_migrate under your PATH.
See CONTRIBUTING for details.
