Hello! Welcome to the fifth lesson in our module on "Cluster Interaction and Troubleshooting."
In our previous lesson, we explored kubectl logs, your tool for viewing the output streams of an application running inside a container. You learned how this is indispensable for understanding application-level errors, especially for debugging crashing pods with the --previous flag. However, logs only tell you what the application has been designed to print. What if you need to go a level deeper?
This lesson introduces kubectl exec, a command that gives you a shell inside a running container. Think of it as the Kubernetes equivalent of docker exec, a concept you're likely familiar with. For a Platform Engineer, this is the ultimate tool for live, interactive debugging. You can inspect the container's filesystem, check network connectivity from its perspective, or run diagnostic utilities that aren't exposed via logs.
By the end of this lesson, you will be able to confidently use kubectl exec to enter a container and perform diagnostic tasks, completing your essential troubleshooting toolkit alongside get, describe, and logs.
1. What is kubectl exec and When Should You Use It?
At a high level, kubectl exec allows you to run a command inside a specific container that is already running in a Pod. The Kubernetes API server facilitates a connection to the kubelet on the node hosting the Pod, which then interfaces with the container runtime (like Docker or containerd) to execute your command.
To understand the mechanics and common use cases, let's start with a foundational reading.
Kubectl Exec Command: Syntax, Best Practices & Examples
The article "Kubectl Exec Command: Syntax, Best Practices & Examples" from unyaml.com provides an excellent overview of what kubectl exec is, how it works, and the scenarios where it becomes incredibly useful.
Please read the first two sections: "What is Kubectl Exec Command?" and "When to use Kubectl Exec Command". Focus on understanding the flow from your client to the container and the key troubleshooting scenarios presented.
To summarize, you'll reach for kubectl exec when kubectl logs isn't enough. Common situations include:
- Inspecting the Environment: Verifying the contents of a configuration file that was mounted via a ConfigMap, or checking the values of environment variables.
- Testing Network Connectivity: Running
pingorcurlfrom inside the Pod to diagnose connectivity issues to other services within the cluster or to external endpoints. This is crucial for debugging network policies or service discovery problems. - Running Diagnostic Tools: Using command-line tools that are bundled with your application image, such as a database client (
psql,mysql) to connect to a database or a performance tool (top) to check resource usage.
2. Executing Commands: From One-Liners to Interactive Shells
Now for the practical part. There are two main ways to use kubectl exec: running a single, non-interactive command, or opening a persistent, interactive shell session.
Running a Single Command
The simplest use is to execute a command and see its output. The syntax is:
kubectl exec <pod-name> -- <command> [args...]
The double dash (--) is important. It separates the kubectl arguments from the command you want to run inside the container. Without it, kubectl might misinterpret arguments intended for your command as its own.
For example, to list the files in the /etc directory of a pod named api-gateway-xyz:
kubectl exec api-gateway-xyz -- ls -l /etc
Getting an Interactive Shell
This is the most powerful and common use case. It gives you a terminal session inside the container. For this, you need to use the -i (interactive, keeps STDIN open) and -t (allocates a pseudo-TTY) flags, almost always combined as -it.
The syntax is:
kubectl exec -it <pod-name> -- <shell-executable>
The shell executable is typically /bin/bash or, for many minimal container images (like those based on Alpine Linux), /bin/sh.
# Get a bash shell in the 'api-gateway-xyz' pod
kubectl exec -it api-gateway-xyz -- /bin/bash
# If bash isn't available, try sh
kubectl exec -it api-gateway-xyz -- /bin/sh
Once inside, you can run commands freely until you type exit or press Ctrl+D.
Let's watch a quick video demonstration to see this in action.
Kubectl Basic Commands - Create and Debug Pod in a Minikube cluster | Kubernetes Tutorial 18
This clip from "TechWorld with Nana" provides a clear demonstration of using kubectl exec -it to get an interactive terminal inside a container for debugging.
Please watch from 09:17 to 10:13. Notice how she uses exec to enter the container and confirms she is in a different environment by running commands.
Dealing with Multi-Container Pods
Your experience with platforms like EKS and AKS means you'll eventually encounter Pods with multiple containers (e.g., an application container and a sidecar for service mesh proxy or log shipping). If you run kubectl exec on such a Pod without specifying a container, you'll get an error.
You must use the -c or --container flag to target the correct one.
kubectl exec -it <pod-name> -c <container-name> -- /bin/bash
For a deeper dive into the syntax variations, including the -c flag, the unyaml.com article is a great reference.
Kubectl Exec Command: Syntax, Best Practices & Examples
Let's refer back to the "Kubectl Exec Command" article to solidify our understanding of the command's syntax, especially for multi-container pods.
Please review the sections "Syntax Kubectl in Clusters, Containers, Nodes, and Pods" and "How to Get SSH or Terminal Access to the Container on the POD Using kubectl exec". Pay close attention to the syntax for multi-container pods.
Test your understanding!
You are troubleshooting a pod named frontend-d84bf5.... You run kubectl describe pod frontend-d84bf5... and see that it has two containers: nginx-app and envoy-proxy.
You suspect a configuration error inside the nginx-app container. What is the full kubectl command you would use to open an interactive shell inside that specific container?
Show answer
The correct command is:
kubectl exec -it frontend-d84bf5... -c nginx-app -- /bin/sh
(Using /bin/bash would also be correct, but /bin/sh is a safer default as it's present in more minimal images).
The key parts are:
kubectl exec -it: To get an interactive terminal.frontend-d84bf5...: The name of the pod.-c nginx-app: To specify the target container within the pod.-- /bin/sh: The command to run to start the shell.
3. Best Practices and What to Avoid
While kubectl exec is a powerful debugging tool, it should be used judiciously. As a Platform Engineer, it's vital to understand that it's a manual intervention, not a standard administrative practice. Changes made via exec are ephemeral—they happen inside the container's filesystem and will be lost if the container restarts.
This final reading highlights the "do's and don'ts" of using kubectl exec.
Kubectl Exec Command: Syntax, Best Practices & Examples
To round out your knowledge, let's review some important best practices. Using this command improperly can lead to non-reproducible environments and mask underlying issues.
Please read the section "Things to Avoid when Using kubectl exec". This is critical for developing the right mindset as a Platform Engineer.
Key principles to remember:
- Debug, Don't Administer: Use
execfor inspection and diagnosis. If you need to change a file, the correct approach is to update the source (e.g., a ConfigMap or Docker image) and redeploy. - Security is Paramount: Access to
execis a high-level privilege. In a production environment, this access is typically restricted using Role-Based Access Control (RBAC), a topic we will cover later. - Expect Minimal Tools: Production container images are often stripped of all non-essential binaries to reduce size and attack surface. Don't be surprised if tools like
curl,ping, or evenbashare missing.
Conclusion
You have now added kubectl exec to your Kubernetes command-line toolkit. You understand not just how to use it, but more importantly, when and why to use it—and when not to. This skill bridges the gap between observing a Pod from the outside (describe, logs) and investigating its internal state directly.
Key Takeaways:
kubectl execruns commands inside a running container, similar todocker exec.- Use
-itto open an interactive shell (e.g.,kubectl exec -it my-pod -- /bin/sh). - For Pods with multiple containers, you must use the
-c <container-name>flag to specify your target. execis an essential tool for interactive debugging but should not be used for routine configuration or management, as any changes are ephemeral.
In our previous lessons, we've assembled a powerful set of tools: get to see status, describe to see events, logs to see application output, and now exec to go inside the container. In our next and final lesson of this module, we will put it all together to diagnose and resolve some of the most common Pod failure scenarios you'll encounter in the wild, such as ImagePullBackOff and CrashLoopBackOff.