Run kubectl exec -it <pod-name> -- /bin/sh (or swap in /bin/bash) to open an interactive shell in a running pod. Add -c <container> when the pod runs more than one container, and -n <namespace> if it is not in your current default. When the image has no shell at all, kubectl debug is the workaround to reach for instead.
TL;DR:
- Use interactive mode for a shell, omit it for quick checks, and put the separator before commands so Kubernetes does not parse their flags.
- If the image lacks both common shells or the container has crashed, use an ephemeral debug container; confirm cluster support before relying on that workflow.
- Exec defaults to the first listed container, so specify the intended container for scripts and production work, and verify the pod and namespace before connecting.
- Treat pod execution as privileged access: scope RBAC grants to needed namespaces, audit sessions, and remember that edits or package installs disappear after container restarts.
Table of Contents
- Copy-ready kubectl exec examples and what each flag does
- Picking the right container and namespace in multi-container pods
- Why kubectl exec fails and how to fix it fast
- When exec can't reach a shell: debug and ephemeral containers
- Keeping pod shell access secure and auditable
- How a desktop client speeds up pod terminal work
- A quick checklist before you exec into anything
- Faster pod terminals without leaving your workflow
- FAQ
- Sources
Copy-ready kubectl exec examples and what each flag does
Once you know the base command, the flags are what make it reliable across different pods and images. Here is the pattern in practice:
kubectl exec -it my-pod -- /bin/shopens an interactive shell using the lightest shell available.kubectl exec -it my-pod -- /bin/bashdoes the same when the image ships Bash.kubectl exec my-pod -- ls /var/logruns a one-off command without opening a session at all.kubectl exec -it deploy/my-app -- /bin/shtargets a pod behind a Deployment without looking up its name first.kubectl exec -it svc/my-service -- /bin/shdoes the same through a Service.
The -i flag passes your terminal's stdin into the container, and -t allocates a TTY so the shell behaves interactively, including things like command history and arrow keys. Drop both and you get a one-shot command instead of a live session, which is exactly what you want for quick checks like reading a file or listing a directory.
The -- separator is not optional punctuation. It tells kubectl where its own flags stop and the command for the container begins, which matters the moment you run something like kubectl exec my-pod -- ls -la. Without it, kubectl can try to parse -la as its own flag and fail or misbehave, as documented in the kubectl exec reference.
Picking the right container and namespace in multi-container pods
Sidecars, init containers, and service meshes mean a lot of pods run more than one process these days, and exec defaults to the first container listed in the pod spec, which is not always the one you want.
- Run
kubectl get pod my-pod -o jsonpath='{.spec.containers[*].name}'to list every container name. - Run
kubectl describe pod my-podfor a fuller view, including container state and recent events. - Add
-c <container-name>to target a specific one, for examplekubectl exec -it my-pod -c app -- /bin/sh. - Check for a
kubectl.kubernetes.io/default-containerannotation on the pod. It changes which container exec picks by default.
In a pod with an init container, a main app container, and a logging sidecar, guessing wrong means you land in the sidecar's shell with none of the application's files in sight. For scripted or production work, always pass -c explicitly rather than relying on the default, per the kubectl exec documentation.
Why kubectl exec fails and how to fix it fast
Most exec failures fall into a handful of patterns, and each has a quick diagnostic step.
- No shell in the image. An error like "executable file not found in $PATH" means the image has no
/bin/shor/bin/bashat all, common with distroless or minimal base images. Try the other shell path first; if neither exists, move tokubectl debug. - OCI runtime exec failed. This usually points to a container that is not actually running. Check
kubectl get pod my-podfor its phase andkubectl describe pod my-podfor container status and node conditions. - Permission denied or forbidden. Run
kubectl auth can-i create pods/exec --namespace <ns>to confirm your access. A "no" means you need a Role and RoleBinding that grant thepods/execsubresource, as described in the Kubernetes RBAC documentation. - Pod isn't Running. A pod stuck in
CrashLoopBackOffcannot be exec'd into reliably. Checkkubectl logs my-pod --previousandkubectl describe pod my-podfor the actual failure before trying to shell in again.
Pro Tip: Any file edit or package install you make inside a running container disappears on the next restart, so treat exec sessions as read-only diagnostics and fix problems in the image or manifest instead.
When exec can't reach a shell: debug and ephemeral containers
Ephemeral containers solve the case exec cannot: a crashed container or a distroless image with no shell to attach to. They add a temporary debugging container to an existing pod's namespace without restarting it, as defined in the Kubernetes documentation on ephemeral containers.
kubectl debug my-pod -it --image=busybox --target=app-containerattaches a debug image and shares the target container's process namespace.kubectl debug my-pod -it --copy-to=my-pod-debug --container=appcopies the pod, letting you change its image or add tools without touching the live workload.- Use
--targetwhen you just need to look inside a running process; use--copy-towhen you need to change something and keep the original pod untouched.
Ephemeral containers depend on the feature being available on your cluster's server version, so confirm support before building a workflow around them.
Keeping pod shell access secure and auditable
pods/exec is effectively privileged access to whatever that container can see and touch, so it deserves the same scrutiny as production SSH. Grant it through RBAC rules scoped to specific namespaces and roles, never cluster-wide by default, and expect it to show up in your audit logs.
A stronger pattern for production clusters is a just-in-time access gateway paired with short-lived credentials, which keeps exec sessions temporary and creates an audit trail independent of the cluster's own logs, as outlined in this guide to securing production debugging. Where possible, lean on logs, metrics, and ephemeral debug sessions before reaching for a live shell. After an incident or maintenance window, revoke or narrow the bindings you granted rather than leaving standing access in place.

How a desktop client speeds up pod terminal work
We built Kubezilla Desktop around the fact that exec commands are easy to type but tedious to repeat across clusters, namespaces, and terminal tabs all day. Our interface puts pod terminals, logs, and resource views in one window instead of several CLI sessions and browser tabs.
We support connecting to multiple clusters at once and managing resources in real time, without routing through a VPN or bastion host for every session. Kubeconfigs stay stored locally on the machine running the app, and the client itself is built in Rust for a lightweight footprint. None of this replaces kubectl: scripting, automation, and CI pipelines still run through the CLI, while the desktop client fits the moments you are manually checking a pod, comparing containers, or jumping between clusters.

A quick checklist before you exec into anything
Years of running pod shells for debugging taught me to slow down before typing the command, not after.
- Confirm your kubeconfig context points at the right cluster and namespace.
- Check pod state and recent logs before assuming you need a shell at all.
- Specify
-cand-nexplicitly rather than relying on defaults. - Try a non-interactive command first to confirm the shell path exists.
- Reach for an ephemeral container when the image is minimal or distroless.
- Review who had exec access afterward, especially on production namespaces.
Faster pod terminals without leaving your workflow
Checking a pod's shell shouldn't mean juggling kubeconfig files, VPN connections, and five open terminal windows. Kubezilla Desktop gives you built-in pod terminals, multi-cluster access, and local kubeconfig storage in one native app, so switching between clusters during a debugging session takes a click instead of a context switch.

| Feature | What it does for you |
|---|---|
| Built-in pod terminals | Open a shell in any pod without a separate terminal window |
| Multi-cluster access | Switch clusters without reloading kubeconfig files manually |
| Local kubeconfig storage | Keeps credentials on your machine, not synced to the cloud |
Our plan runs $5 EUR per month, and you can see the full feature set on the Kubezilla Desktop product page before deciding if it fits your workflow.
FAQ
What is the command to get a shell into a Kubernetes pod?
Run kubectl exec -it <pod-name> -- /bin/sh or substitute /bin/bash if the image includes it. This opens an interactive terminal session inside the container, as documented in the Kubernetes guide to getting a shell in a running container.
How do I exec into a specific container in a multi-container pod?
Add the -c flag followed by the container name, for example kubectl exec -it my-pod -c app -- /bin/sh. Without it, exec defaults to the first container listed in the pod spec, which may not be the one you intend to inspect.
Why does kubectl exec say the executable file was not found?
That error means the container's image does not include /bin/sh or /bin/bash, which is common with distroless or minimal base images. In that case, use kubectl debug to attach an ephemeral container with its own shell instead.
What permissions do I need to use kubectl exec?
You need RBAC permission for the pods/exec subresource in the namespace you are targeting. Test your access with kubectl auth can-i create pods/exec --namespace <ns>, and if it returns no, ask an administrator to grant a Role bound to your account, per the Kubernetes RBAC documentation.
Can I open a pod shell without using the terminal?
Yes, a desktop client like Kubezilla Desktop provides a graphical pod terminal alongside multi-cluster access and local kubeconfig storage, so you can open a shell with a click instead of typing the full exec command.
