Kubernetes is a container orchestrator that lets you automate deployments across multiple physical machines. Starting a shell session to a container in a Kubernetes cluster isn’t the same as using Secure Shell (SSH) on a physical server. Although containers should be stateless and capable of running without intervention, sometimes you may need a shell to debug issues or extract data.
kubectl exec lets you connect to containers inside your cluster. It’s part of the full kubectl CLI utility for interacting with Kubernetes installations. The
exec command streams a shell session into your terminal, similar to
Here’s the simplest invocation to get a shell to the
kubectl will connect to your cluster, run
/bin/sh inside the first container within the
demo-pod pod, and forward your terminal’s input and output streams to the container’s process. In this article, you will examine the scenarios where
kubectl exec is useful, what each section of the command does, and how you can customize the shell connection.
When to use kubectl exec
Managing containerized workloads in a Kubernetes cluster requires different processes than those used for applications on a traditional bare-metal server. Because you must drill down from the cluster host to the container instances that deploy your system, there is an extra layer between you and your software.
Kubernetes’s strength is its ability to distribute replicas across physical machines (nodes). Even if you could use SSH for management, you’d have to keep track of which node was running each container.
kubectl exec lets you specify the container to connect to without worrying about the Kubernetes node it’s on.
Starting a shell inside a container is most commonly used when you’re debugging a problem. After exhausting other avenues of inquiry, such as the logs produced by a container, you may have no other option than to inspect it from the inside.
By running the shell commands, you can see the container’s entire file system and check if the environment is as you expected. It can also help you identify whether a critical file is missing or locked, or find instances of misconfigured environment variables.
Actions to avoid when using kubectl exec
kubectl exec gives you full shell access, there’s nothing to stop you from modifying the container, too. This allows you to add extra software packages to aid in your debugging. The extra software packages are sometimes necessary when you are connected to a container that uses a minimal base image where common tools may be missing.
Nonetheless, you should refrain from substantially altering the container’s environment. Don’t update existing software packages or use
kubectl exec as a way to replace your application’s source code. These operations would depart from the model of immutability and reproducibility that’s the foundation of the container movement. Instead, you should rebuild your container image then deploy the new version into your Kubernetes cluster.
kubectl exec is a helpful tool when you want to inspect the state of a container in your cluster. It shouldn’t generally be used to alter the state, except in specific cases where you’re adding extra debugging packages or fixing a one-off problem in the environment.
Kubectl exec syntax
Unlike a simple
ssh user@server command, kubectl exec requires a few extra arguments to set up an interactive shell session. Let’s break down the command shown above:
This specifies that you want to run the
/bin/sh command in the first container within your
demo-pod pod. The
-- separates the command to run from the
kubectl arguments. Anything after the
-- will be passed to the container, as opposed to
-it is equivalent to using the
-t) flags. These instruct kubectl to route your terminal’s
stdin input stream to the container (
-i) and treat it as a TTY (
-t). This sets up an interactive session where you can supply input to the process inside the container. Without these flags, you’d see a read-only output stream.
Whereas SSH automatically starts a shell process and binds your terminal’s input and output streams, kubectl makes each of these aspects customizable. You don’t have to start a shell in the container; you could run an arbitrary process instead, supply it some interactive input, and receive its output:
Like all other kubectl commands,
exec works with the cluster connection defined by your
KUBECONFIG environment variable. This should reference a kubeconfig file containing your cluster’s connection details.
The specified container name must exist within the default cluster namespace. Use the global
--namespace flag to change this when you’re referencing a container in a different namespace:
Pods and containers
Containers in a Kubernetes cluster reside within Pods. As each Pod can incorporate several containers,
kubectl exec supports an additional argument to let you specify a Pod and container to connect to:
In this example, your connection would be to the
demo-container container within the
demo-pod pod. In the previous steps, we omitted the container name and only indicated the pod. In this case, kubectl automatically connects to the container with the
kubectl.kubernetes.io/default-container annotation or the first container in the Pod when the annotations are not used.
You can also directly reference a higher-level resource, such as a deployment. This reference lets you rapidly connect to a container without needing to know its exact name:
The command above would give you a shell session to the first container within the
demo-deployment deployment. It removes the need to run
kubectl get pods to discover Pod names before you use
kubectl exec supports a couple of extra options that let you customize its operation:
-q): This disables all output from kubectl itself. You’ll only see output produced by the process running in the container.
--pod-running-timeout: This lets you customize the timeout before kubectl gives up trying to connect when no matching Pods are running. The default value of
1m0smeans kubectl will wait for up to a minute for a Pod to be available.
These arguments should be passed to the kubectl portion of the command before the -- separator that commences the in-container section.
Alternatives to kubectl exec
kubectl exec is the best option for getting a shell to a Kubernetes container. It’s designed specifically for this purpose and circumvents all the issues of identifying the correct physical node to connect to.
If you really need an alternative, perhaps because you must connect from a system without kubectl, you could consider running an SSH daemon inside your container. Beware that this increases your security attack surface and goes against the idea of each container having one single purpose.
Another option is setting up a web-based Kubernetes dashboard. Many popular options, including the official dashboard, are capable of providing interactive shell sessions within your browser.
kubectl exec command lets you start a shell session inside containers running in your Kubernetes cluster. This command lets you inspect the container’s file system, check the state of the environment, and perform advanced debugging tools when logs alone don’t provide enough information.
Manual use of shell commands should be your last resort for managing your containers. Day-to-day monitoring of Kubernetes metrics and critical events is better served by dedicated platforms, such as Datadog, which lets you use prebuilt dashboards to keep tabs on your cluster’s health.
If you are looking for a serverless platform to test these shell scripts and share them with your team, check out Airplane. With Airplane, you can turn shell scripts into powerful internal tools without having to manage your own infrastructure.