Skip to content
Rahul Shishodiaon GitHub LinkedIn profile

kubectl debug and kubectl cp

Throwaway debug pod (kubectl run)

Spin up a short-lived Pod in the same namespace as the workload to test DNS, Service connectivity, or Ingress paths from inside the cluster.

kubectl run debug-pod -n q32 \
  --image=busybox:latest \
  --restart=Never -it --rm -- \
  wget -qO- http://backend-svc.q32.svc.cluster.local
Flag / partWhy
--restart NeverOne-shot Pod; does not respawn after the command exits
-it --rmInteractive shell session; Pod deleted when you exit
--Everything after is the container command (not kubectl flags)
backend-svc.q32.svc.cluster.localCluster DNS: <service>.<namespace>.svc.cluster.local

Other checks from the same pattern:

# DNS resolution only
kubectl run debug-pod -n q32 --image=busybox:latest --restart=Never -it --rm -- \
  nslookup backend-svc.q32.svc.cluster.local

# Short name works inside the same namespace
kubectl run debug-pod -n q32 --image=busybox:latest --restart=Never -it --rm -- \
  wget -qO- http://backend-svc

# Interactive shell when you need several commands
kubectl run debug-pod -n q32 --image=busybox:latest --restart=Never -it --rm -- sh
  • Use when the problem is networking/DNS/Service, not a specific crashing Pod
  • Faster than kubectl debug when you do not need to attach to an existing Pod

kubectl debug (ephemeral containers)

Ephemeral containers are temporary debug containers added to a running Pod without restarting it. Essential for distroless or minimal images that have no shell.

# Attach an ephemeral busybox to a running pod, sharing its process namespace
kubectl debug pod/mypod -it --image=busybox:1.36.1 --target=app

# Without --target: ephemeral container runs isolated (can't see app processes)
kubectl debug pod/mypod -it --image=busybox:1.36.1
  • --target=<container>: share the process namespace of that container
  • The ephemeral container disappears when you exit; the Pod is not restarted
  • Ephemeral containers are not listed in kubectl get pod READY count

kubectl debug with pod copy

When you need to modify the Pod spec for debugging (e.g. change the image, add a shell):

# Create a copy of the pod with a different image (original pod keeps running)
kubectl debug pod/mypod -it --image=ubuntu:22.04 --copy-to=mypod-debug

# Copy pod but change the specific container's image
kubectl debug pod/mypod -it --image=busybox --copy-to=debug-pod --share-processes
  • --copy-to: name of the new debug Pod
  • --share-processes: all containers in the copy share a PID namespace
  • Clean up the debug pod when done: kubectl delete pod mypod-debug

When to use which approach

ScenarioApproach
Test Service / DNS from inside clusterkubectl run debug-pod … -- wget or nslookup
App has no shell (distroless)kubectl debug --target=<container>
Need to inspect running processeskubectl debug --target=<container> with --share-processes
Need to change the image entirelykubectl debug --copy-to=<new-pod>
App crashes before you can execkubectl debug --copy-to=<new-pod> with command: ["sleep", "3600"]

Override command in debug copy

kubectl debug pod/crashing-pod --copy-to=debug --image=nginx:1.25.1 -- sleep 3600
# then exec into the copy
kubectl exec -it debug -- /bin/sh

kubectl cp (copy files to/from pod)

# Pod → local
kubectl cp mypod:/etc/config/app.conf ./app.conf
kubectl cp mypod:/var/log/app.log ./app.log -c sidecar   # specify container

# Local → pod
kubectl cp ./app.conf mypod:/tmp/app.conf
kubectl cp ./config/ mypod:/etc/config/                  # directory

# Across namespaces
kubectl cp mynamespace/mypod:/path/file.txt ./file.txt
  • Requires tar in the container image (not available in fully distroless images)
  • For distroless: use ephemeral debug container first, then cp if needed

Exam tips

  • kubectl run debug pod: put -n <namespace> on the command; use --restart Never with --rm for one-shot probes
  • Service URL from another namespace: include namespace in DNS (svc.ns.svc.cluster.local)
  • kubectl debug with --target requires the cluster to support ephemeral containers (K8s ≥ 1.23 GA): assume supported on exam
  • Without --target, ephemeral container cannot see the app's processes
  • kubectl cp silently fails on distroless (no tar): use debug instead
  • Clean up debug pods after use to avoid confusion during the exam