Kubectl exec is the command you use to run a command inside a running Kubernetes pod, and the most common examples are kubectl exec -it <pod-name> -- /bin/sh for an interactive shell and kubectl exec <pod-name> -- <command> for a one-off command. This article walks through those and several other real-world examples, explains the flags, and covers troubleshooting and safety.
What kubectl exec does
Kubernetes runs containers in pods. When you need to inspect a container from the inside—check environment variables, look at logs that aren’t written to stdout, test network connectivity, or debug a crash—kubectl exec sends a command to the container’s main process namespace. It is the Kubernetes equivalent of docker exec, but it works across a cluster through the API server.
The basic syntax is:
kubectl exec [flags] POD_NAME -- COMMAND [args...]
The double dash (--) separates kubectl flags from the command you want to run inside the container. Everything after it is passed verbatim to the container’s shell or executable. If you omit the double dash, kubectl may try to parse your command as its own flag, which causes confusing errors.
Prerequisites and permissions
To use kubectl exec you need:
- kubectl installed and configured to talk to your cluster (
kubectl config current-contextshows which cluster you’re on). - The pod must be running (not Pending or Completed). You can check with
kubectl get pods. - RBAC permissions: your user or service account needs
pods/execcreate permission. Without it you’ll get a Forbidden error. - The container image must contain the binary you’re calling. A minimal distroless image may not have
/bin/shorbash; in that case you can still run a static binary if it exists, or you may need to usekubectl debugto add a sidecar with shell tools.
Common kubectl exec examples
Here are the commands you’ll use most often, with the exact flags.
1. Open an interactive shell
kubectl exec -it my-pod -- /bin/sh
The -i keeps STDIN open, and -t allocates a pseudo-TTY so you get a proper terminal with prompt and line editing. For images that have bash, use /bin/bash. If the pod has multiple containers, you must specify one with -c:
kubectl exec -it my-pod -c my-container -- /bin/bash
2. Run a single command and get output
kubectl exec my-pod -- env
This prints the environment variables and exits. No -it is needed for non-interactive commands. Other useful one-liners:
kubectl exec my-pod -- ls /app kubectl exec my-pod -- cat /etc/hosts kubectl exec my-pod -- whoami
3. Run a command in a specific container
kubectl exec my-pod -c sidecar-container -- tail -f /var/log/access.log
If you omit -c and the pod has multiple containers, kubectl uses the first container in the pod spec, which is not always what you want.
4. Use a custom working directory
kubectl exec my-pod -- /bin/sh -c 'cd /tmp && ls -la'
Pass a shell command string with sh -c to chain commands. This is also how you use pipes and redirection:
kubectl exec my-pod -- /bin/sh -c 'echo $HOSTNAME'
Note that environment variables are expanded by the shell inside the container, not by your local shell, so single quotes are important.
5. Copy a file out of a pod
While not strictly exec, kubectl cp is the companion command for copying files:
kubectl cp my-pod:/etc/config.yaml ./config.yaml kubectl cp ./local.txt my-pod:/tmp/
Under the hood, kubectl cp uses exec to run tar commands inside the container. It requires the container to have tar installed.
How to choose the right flags
Flag selection depends on what you need:
- Interactive shell: always use
-it. Without-tyou won’t get a prompt; without-iyou can’t type input. - One-off read-only command: no flags, just
-- command. - Command that needs input (like
mysql -p): use-ibut not necessarily-tif you’re piping input. - Pod with multiple containers: always add
-c container-nameto be explicit. - Namespace: add
-n my-namespaceif the pod isn’t in the default namespace.
You can also use a deployment or service name with deploy/ or svc/ prefix, but that only works if the resource has a single replica; otherwise kubectl picks one pod arbitrarily. It’s safer to use the exact pod name from kubectl get pods.
Common problems and how to fix them
These are the errors you’ll run into and what they mean:
- “Unable to use a TTY – container is not running or does not exist”: The container is not in a running state, or you specified the wrong name. Check
kubectl get podsand the pod’s status. - “executable file not found in $PATH”: The binary isn’t in the container’s PATH. Use the full path, e.g.
/bin/shinstead ofsh, or check the image’s filesystem. - “Error from server (Forbidden)”: Your RBAC role doesn’t allow pods/exec. Ask your cluster admin to grant you the appropriate permission.
- “cannot exec into a container in a completed pod”: The pod has finished (e.g., a Job). You can’t exec into a terminated container; check logs instead.
- Command hangs: The container may be waiting for input because you didn’t use
-i, or the command itself is long-running (liketail -f). Use--with a timeout or run it in the background.
If the pod is in a CrashLoopBackOff, you can still try exec, but the container may restart before you connect. A better approach is kubectl debug to start a temporary sidecar with debugging tools, or kubectl logs -p to see the previous crashed container’s logs.
Safety and security considerations
kubectl exec is powerful and should be used with care:
- It bypasses the container’s entrypoint: exec runs directly in the container, not through the Docker CMD, so it can be used to access data that the application may not expose.
- It runs as the container’s configured user: unless the image sets a non-root user, you may be root inside the container. That’s still limited by the container’s security context, but be careful with destructive commands.
- Don’t use exec for routine monitoring: prefer
kubectl logs, metrics, or read-only endpoints. Exec creates load on the API server and the kubelet. - Audit and RBAC: cluster admins should restrict pods/exec to only those who need it, and consider using Pod Security Standards to prevent privileged containers.
- Never store secrets in exec commands: they appear in shell history and potentially in audit logs.
For production debugging, consider ephemeral containers (kubectl debug) which allow you to add a new container to a running pod without restarting it, and are easier to audit.
Alternatives to kubectl exec
Depending on what you’re trying to do, other tools may be more appropriate:
- kubectl logs: for stdout/stderr output, especially with
-fto follow and--previousfor crashed containers. - kubectl cp: for copying files in and out, as noted above.
- kubectl port-forward: to access a service or pod from your local machine without exec.
- kubectl debug: to create a temporary container with debugging tools, or to copy a pod and change its command.
- kubectl attach: to attach to a running process’s stdin/stdout, similar to docker attach. This is rarely used but exists.
If you find yourself exec’ing often to run the same commands, consider adding a sidecar that exposes an HTTP endpoint or a shell via a web console, or using a tool like Octant or Lens that provides a GUI for exec.
Frequently Asked Questions
How do I exec into a pod with multiple containers?
Use the -c flag to specify the container name. For example: kubectl exec -it my-pod -c my-container -- /bin/sh. If you don’t, kubectl uses the first container in the pod spec, which may not be the one you want.
What is the difference between kubectl exec and kubectl attach?
Exec starts a new process inside the container, while attach connects to the container’s main process (PID 1) and streams its stdin/stdout. Attach is rarely needed; exec is the standard way to run commands.
Can I exec into a pod that is not running?
No. The container must be in a running state. For completed pods (like Jobs), you can’t exec; use kubectl logs instead. For CrashLoopBackOff, you may catch a window before it restarts, but it’s unreliable.
Why do I get “executable file not found” when I run a command?
The binary you’re trying to run isn’t in the container’s PATH or isn’t installed. Use the full path (e.g., /bin/sh) or check the image’s filesystem with ls /bin. Some minimal images don’t include a shell at all.
Is kubectl exec safe for production?
It’s safe if you have proper RBAC and use it for debugging. Avoid making changes via exec in production; use deployments and config maps. Also be aware that exec commands can be audited by the API server, so avoid passing secrets.
How do I run a command with environment variables?
Use /bin/sh -c and single quotes so the shell inside the container expands the variables. For example: kubectl exec my-pod -- /bin/sh -c 'echo $MY_VAR'. Double quotes would let your local shell expand it first (usually to nothing).
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It