kubectl cp
Copy files and directories to and from containers in pods. Uses tar internally to transfer data.
kubectl cp [SOURCE] [DEST] [flags]Common Flags
| Flag | Short | Description |
|---|---|---|
| --container | -c | Container name to copy to/from in multi-container pods |
| --namespace | -n | Namespace of the pod |
| --no-preserve | — | Do not preserve the ownership and permissions of the copied files |
| --retries | — | Number of retries to copy (default 0) |
Examples
Copy a file from local to a pod
kubectl cp ./config.yaml my-pod:/etc/app/config.yamlCopy a file from a pod to local
kubectl cp my-pod:/var/log/app.log ./app.logCopy a directory to a pod
kubectl cp ./configs/ my-pod:/etc/app/configs/Copy from a specific container
kubectl cp my-pod:/data/export.csv ./export.csv -c appCopy from a pod in a specific namespace
kubectl cp production/my-pod:/var/log/app.log ./app.logCopy without preserving permissions
kubectl cp ./script.sh my-pod:/tmp/script.sh --no-preserveWhen to Use kubectl cp
kubectl cp copies files between your local filesystem and containers running in pods. It is primarily used for debugging tasks: extracting log files, copying diagnostic tools into containers, or retrieving data exports from running applications.
Basic File Operations
Copy files in both directions using the pod:path syntax:
# Copy a local file into a pod
kubectl cp ./config.yaml my-pod:/etc/app/config.yaml
# Copy a file from a pod to local
kubectl cp my-pod:/var/log/app.log ./app.log
# Copy an entire directory
kubectl cp ./scripts/ my-pod:/tmp/scripts/
# Copy a directory from a pod
kubectl cp my-pod:/var/log/ ./pod-logs/
Namespace-Qualified Paths
When working with pods in non-default namespaces, prefix the pod name with the namespace:
# Copy from a pod in the production namespace
kubectl cp production/my-pod:/data/report.csv ./report.csv
# Copy to a pod in staging
kubectl cp ./fix.sh staging/my-pod:/tmp/fix.sh
# You can also use the -n flag
kubectl cp my-pod:/data/report.csv ./report.csv -n production
Multi-Container Pods
Specify the container with the -c flag:
# Copy from the application container
kubectl cp my-pod:/app/logs/error.log ./error.log -c app
# Copy a debug tool into the sidecar
kubectl cp ./tcpdump my-pod:/tmp/tcpdump -c debug
How It Works Internally
kubectl cp uses tar to package and transfer files. When you copy a file to a pod, kubectl:
- Creates a tar archive of the local file.
- Streams it through the API server.
- Executes
tar -xfinside the container to extract the file.
When copying from a pod:
- Executes
tar -cfinside the container to create an archive. - Streams it back through the API server.
- Extracts it locally.
This means the container must have tar installed. Many minimal and distroless images do not include tar.
Working Without tar
When the container lacks tar, use alternative approaches:
# Copy a file from a container using exec and cat
kubectl exec my-pod -- cat /var/log/app.log > app.log
# Copy binary data using base64
kubectl exec my-pod -- base64 /data/file.bin > file.b64
base64 -d file.b64 > file.bin
# Copy a file into a container using exec
kubectl exec -i my-pod -- sh -c 'cat > /tmp/script.sh' < script.sh
# Make it executable
kubectl exec my-pod -- chmod +x /tmp/script.sh
Common Debugging Workflows
# Extract a heap dump from a Java application
kubectl cp my-pod:/tmp/heapdump.hprof ./heapdump.hprof -c app
# Copy diagnostic tools into a minimal container
kubectl cp ./strace my-pod:/tmp/strace
kubectl exec my-pod -- chmod +x /tmp/strace
# Retrieve a database export
kubectl cp my-pod:/tmp/db-backup.sql ./db-backup.sql -c postgres
# Copy configuration for inspection
kubectl cp my-pod:/etc/nginx/nginx.conf ./nginx-live.conf
# Compare live config with expected config
diff nginx-expected.conf nginx-live.conf
Large File Considerations
kubectl cp is not designed for large file transfers. The data streams through the API server, which has request size limits and timeout constraints:
# For large files, use a shared volume instead
# 1. Create a PVC
# 2. Mount it to a pod with tools installed
# 3. Use the tool pod to transfer data to/from external storage
# Or use exec with compression for moderate-sized files
kubectl exec my-pod -- tar czf - /data/large-dir | gzip -d > large-dir.tar
Security Notes
Files copied into containers are not persisted across restarts. Any file copied via kubectl cp exists only in the container's writable layer and is lost when the pod is recreated. For permanent configuration changes, update the container image, ConfigMap, or Secret.
Be cautious about copying files from untrusted containers. The tar extraction can potentially overwrite files outside the intended directory through path traversal attacks in crafted tar archives.
Best Practices
Use kubectl cp for one-off debugging tasks only. For regular data exchange, use ConfigMaps, Secrets, or PersistentVolumes. For large data, use object storage like S3 with init containers or sidecar uploaders. Always verify that tar is available in the target container before relying on cp. Prefer kubectl exec with pipe redirections for containers without tar.
Interview Questions About This Command
Common Mistakes
- Trying to use kubectl cp with a container that does not have tar installed, which causes the copy to fail silently or with an error.
- Using kubectl cp for large data transfers instead of proper volume-based solutions like PersistentVolumes or S3.
- Forgetting the namespace prefix format (namespace/pod:/path) when copying from pods in non-default namespaces.