Skip to content
LatchkeyLatchkey home

kubectl cp: Copy Files To and From Pods

kubectl cp copies files and directories between your machine and a container, using tar inside the pod.

For pulling a coverage report out of a CI pod or pushing a fixture in, kubectl cp is the quick path. It relies on tar being present in the container.

What it does

kubectl cp streams files between local paths and a pod:path target. Under the hood it runs tar in the container, so the container image must contain a tar binary. Pod paths use namespace/pod:/path and you select a container with -c.

Common usage

Terminal
# local -> pod
kubectl cp ./fixtures.json mypod:/tmp/fixtures.json
# pod -> local
kubectl cp mypod:/var/log/app.log ./app.log
# specify namespace and container
kubectl cp data/pod-x:/out/report.xml ./report.xml -c runner

Options

Flag / SyntaxWhat it does
<src> <pod>:<path>Copy a local source into the pod
<pod>:<path> <dest>Copy from the pod to local
<ns>/<pod>:<path>Include the namespace in the target
-c, --containerContainer in a multi-container pod
--retries=<n>Retry on transient stream errors (newer kubectl)

In CI

kubectl cp needs tar in the container; distroless or scratch images will not work. Prefer absolute paths and avoid leading / weirdness: a warning about removing a leading slash is normal. For large or critical artifacts, an init/sidecar that writes to a shared volume is more robust than cp.

Common errors in CI

"error: ... tar: not found" or "executable file not found in $PATH" means the container has no tar; bake one in or use a different image. "error: unable to upgrade connection: container not found" means a wrong container name or the pod restarted mid-copy. "lost connection to pod" on big files means the stream timed out; retry or move smaller chunks.

Using this in CI

A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.

Terminal
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods

# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info

# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes

Frequently asked questions

kubectl cp: Copy Files To and From Pods?
For pulling a coverage report out of a CI pod or pushing a fixture in, kubectl cp is the quick path. It relies on tar being present in the container.
What it does?
kubectl cp streams files between local paths and a pod:path target. Under the hood it runs tar in the container, so the container image must contain a tar binary. Pod paths use namespace/pod:/path and you select a container with -c.
In CI?
kubectl cp needs tar in the container; distroless or scratch images will not work. Prefer absolute paths and avoid leading / weirdness: a warning about removing a leading slash is normal. For large or critical artifacts, an init/sidecar that writes to a shared volume is more robust than cp.
Common errors in CI?
"error: ... tar: not found" or "executable file not found in $PATH" means the container has no tar; bake one in or use a different image. "error: unable to upgrade connection: container not found" means a wrong container name or the pod restarted mid-copy.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card