Skip to main content
In this guide, we explore the power of the kubectl debug command for troubleshooting Kubernetes applications. Unlike kubectl exec, which only lets you run commands in an existing container, kubectl debug enables you to attach a new container to a running pod. This method is particularly useful for debugging without interrupting production workloads.

Why Use kubectl debug?

The kubectl debug command offers several advantages over kubectl exec:
  1. It minimizes disruptions to running pods, making it an ideal choice for production environments.
  2. It is especially helpful when working with distroless images that only include application dependencies and omit shells or debugging utilities.
  3. It provides an effective solution for debugging crashing containers where the container might terminate immediately upon exec.
Moreover, kubectl debug extends beyond pods. You can also attach a debug container to a node, granting access to the node’s filesystem and host namespace.
The image is a slide titled "kubectl debug - why," listing reasons such as minimizing pod disruptions, handling distroless images, and dealing with crashed containers.

Debugging a Distroless Pod

Consider a scenario with a running distroless pod. First, list the pods:
Since the container does not have a shell, attempting to exec into it yields an error:
Use kubectl debug instead of exec when shell access is unavailable due to a minimal image footprint.
Instead, run the debug command that attaches a new BusyBox container with an interactive shell:
The BusyBox container provides an interactive shell so you can inspect executables (such as traceroute or telnet) without disturbing the main container. Exiting the shell terminates the debug container, but you can reattach it if needed:
Review the pod definition to inspect events and container statuses. For instance, after starting the debug container, you can list pods:
And while direct exec for /bin/sh fails due to its absence, using kubectl debug with BusyBox succeeds.
Remember that the resources allocated for ephemeral containers are shared with the main pod. Use lightweight images for debugging purposes.

Inspecting Pod Details with Debug Containers

Once the debug container is attached, you can inspect its activity by reviewing the pod’s event log. The log might include steps such as pulling the BusyBox image, and messages confirming the creation and start of the debug container. A sample output might look like:
Here, the ephemeral container named “debugger-h6qr8” is added. Note that once you exit the shell, its state will change to “Terminated” and it will not restart automatically.

Using the —target Flag

The —target flag of kubectl debug helps specify which container in a multi-container pod should be targeted. By sharing the process namespace with the chosen container, you can inspect its processes and filesystem. For example, let’s deploy an nginx pod:
Debug the pod with BusyBox without the —target flag:
Without —target, you only see processes running in BusyBox. Now, attach the debug container to the nginx container:
After running ps aux, you will see processes associated with the nginx container. You can navigate the filesystem (e.g., into /proc or /etc/nginx/) to further inspect process activity and configuration:
And with further exploration, you can validate that you are viewing the actual environment of the target container.

Copying a Pod for Debugging

When debugging a deployment, you may prefer not to affect the original pod. The —copy-to flag creates a duplicate pod with an attached debug container. Use this option along with —share-processes to facilitate shared process inspection:
This command creates a new pod, “debugging-pod,” that comprises both the primary application container and the BusyBox debug container. Running ps aux in the debugging pod displays processes from both containers:
Inspect your pods to confirm:
Note that the debugging pod is a copy and does not inherit labels from the original. This approach avoids unintended service traffic redirection.

Final Remarks

The kubectl debug command is an essential troubleshooting tool in Kubernetes. Whether dealing with distroless images, diagnosing crashing containers, or investigating process namespaces with the —target flag, this tool enhances your debugging capabilities without disrupting running services. Additionally, the —copy-to option provides a safe way to work on a duplicate pod, ensuring production traffic remains unaffected. For more advanced debugging techniques and configurations, consult the Kubernetes Documentation. Happy debugging, and happy learning!

Watch Video

Practice Lab