kubectl exec runs commands in a running pod container. kubectl exec -it pod -- bash gets an interactive shell. -c container for multi-container. -- separates kubectl flags from the command. The team that uses this for debugging avoids redeploying with debug flags.
Table of contents
- Basic exec
- Interactive shell
- Shell choices
- Multi-container pods
- Running as specific user
- Files transfer via exec
- Debugging with ephemeral containers
- Common pitfalls
- FAQ
Basic exec
Run a single command:
kubectl exec my-pod -- ls /app
Runs ls /app in the container. The -- separates kubectl flags from the command.
Interactive shell
kubectl exec -it my-pod -- bash
-i (stdin), -t (TTY). Drops into a bash shell inside the container. The team that uses this for debugging has direct access to the running process.
Shell choices
Different containers have different shells:
# Debian/Ubuntu-based
kubectl exec -it my-pod -- bash
# Alpine
kubectl exec -it my-pod -- sh
# Distroless (no shell)
kubectl exec -it my-pod -- ls /
The team that has distroless containers uses exec for commands, not shells.
Multi-container pods
kubectl exec -it my-pod -c sidecar -- bash
-c specifies the container. Required when pod has multiple containers. The team that uses this for sidecar debugging.
Running as specific user
kubectl exec -it my-pod -- su -s /bin/bash nobody
Run as a different user inside the container. Useful for testing perms.
Files transfer via exec
Copy a file out:
kubectl exec my-pod -- cat /app/config > local-config
Or copy in (multi-step):
kubectl exec -i my-pod -- bash -c 'cat > /app/config' < local-config
The team that uses kubectl cp instead has a cleaner file transfer.
Debugging with ephemeral containers
K8s 1.23+:
kubectl debug my-pod -it --image=busybox --target=app
Adds an ephemeral debug container to a pod that doesn’t have debugging tools. Useful for distroless images. The team that has distroless containers uses kubectl debug for live troubleshooting.
Common pitfalls
- Missing
-cfor multi-container pods. - Container without bash (alpine, distroless).
- Container with read-only root filesystem (can’t write debug files).
- Container security policy blocking exec. The team that hardens pod security has restricted exec.
FAQ
Can I exec into a distroless container?
Limited - distroless has no shell. Use kubectl debug to add an ephemeral container.
How do I get a root shell in a non-root container?
If the container doesn’t have a root user and no setuid binaries, you can’t. The team that designs for security has containers without root capabilities.
Can I exec from a script?
Yes - kubectl exec pod -- command args. The team that uses this for automation has scripted pod interaction.
Why is kubectl exec hanging?
Either no shell available, or container is unresponsive. The team that uses kubectl logs first has better diagnosis.
Can I run kubectl exec with sudo?
Yes if the container has sudo. kubectl exec -it pod -- sudo bash. The team that has sudo in containers (rare for security) uses this.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: