Migrate Files Between Kubernetes Volumes Using kubectl cp
Transfer files stored in Kubernetes Persistent Volumes from a source cluster to a target cluster using kubectl cp, routing through the local machine as an intermediary.
Prerequisites
kubectlinstalled and configured with contexts for both clusters- Access to both clusters (kubeconfigs set up, e.g., via
aws eks update-kubeconfig) - The source Pod name, namespace, and the path inside the Pod where files are stored
- The target Pod name and namespace
Let's Start
Step 1 — Configure kubectl access to both clusters
Make sure you have kubeconfig entries for both clusters. For example:
aws eks update-kubeconfig --region us-east-1 --name source-cluster-name --profile source-profile
aws eks update-kubeconfig --region us-east-1 --name target-cluster-name --profile target-profile
Verify the contexts are available:
kubectl config get-contexts
Step 2 — Run the migration script
Save the following script as transfer.sh, customize the variables at the top, and run it:
#!/bin/bash
set -euo pipefail
SOURCE_CONTEXT="source-context" # kubectl context for the source cluster
TARGET_CONTEXT="target-context" # kubectl context for the target cluster
SOURCE_POD="source-pod-name"
SOURCE_NAMESPACE="source-namespace"
SOURCE_PATH="/path/in/source-pod"
TARGET_POD="target-pod-name"
TARGET_NAMESPACE="target-namespace"
TARGET_PATH="/path/in/target-pod"
TEMP_LOCAL_DIR="/tmp/k8s-transfer"
# Validate both contexts exist
for ctx in "$SOURCE_CONTEXT" "$TARGET_CONTEXT"; do
if ! kubectl config get-contexts "$ctx" &>/dev/null; then
echo "Error: kubectl context '$ctx' not found" >&2
exit 1
fi
done
# Copy from source pod to local machine
echo "Copying files from $SOURCE_POD..."
mkdir -p $TEMP_LOCAL_DIR
kubectl --context="$SOURCE_CONTEXT" cp $SOURCE_NAMESPACE/$SOURCE_POD:$SOURCE_PATH $TEMP_LOCAL_DIR
# Copy from local machine to target pod
echo "Copying files to $TARGET_POD..."
kubectl --context="$TARGET_CONTEXT" cp $TEMP_LOCAL_DIR/. $TARGET_NAMESPACE/$TARGET_POD:$TARGET_PATH
# Clean up
rm -rf $TEMP_LOCAL_DIR
echo "Transfer complete."
Make it executable and run:
chmod +x transfer.sh
./transfer.sh
info
This approach works best for application assets — uploaded files, media, configuration — that are not part of a database. For database data, use the PostgreSQL dump restore guide instead.