Terminus
Execute Commands in Pods With kubectl

Execute Commands in Pods With kubectl

The short answer

In Kubernetes, to execute a command inside a running Pod’s container, you can use the [.inline-code]kubectl exec[.inline-code] command as follows:

 $ kubectl exec <pod> -- <command>

Where:

  • [.inline-code]pod[.inline-code] is the name of the pod you want to execute a command into.
  • [.inline-code]command[.inline-code] is the command you want to execute.
  • [.inline-code]--[.inline-code] the double dash separates the [.inline-code]kubectl[.inline-code] parameters and flags from the command you want to run and its flags/parameters.

For example:

 $ kubectl exec web-0 -- env

This will execute the [.inline-code]env[.inline-code] command within a Pod named [.inline-code]web-0[.inline-code], resulting in its environment variables being outputted to the terminal window.

[#easily-recall-syntax-with-ai] Easily retrieve this command using Warp’s AI Command Suggestions [#easily-recall-syntax-with-ai]

If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Suggestions feature:

Pressing the [.inline-code]#[.inline-code] symbol at the start of a line will pull up the AI search and then you can enter [.inline-code]kubernetes execute command[.inline-code] to get the command template. You can quickly insert that command into your shell using [.inline-code]CMD+ENTER[.inline-code].

[#handle-executable-not-find] Handling the “command / executable file not found” error [#handle-executable-not-find]

When trying to execute a command within a Pod, you need to make sure that this command is defined in the PATH environment variable of the container, as it might otherwise result in an “executable not found” error. In that case, you can use the full path to the executable.

For example:

 $ kubectl exec web-0 -- /opt/redis-cli --help

This command will execute the [.inline-code]redis-cli[.inline-code] utility located in the [.inline-code]/opt[.inline-code] directory of the Pod named [.inline-code]web-0[.inline-code].

[#run-interactive-commands] Running interactive commands [#run-interactive-commands]

By default [.inline-code]kubectl exec[.inline-code] will run the specified command without being attached to the standard input, which means that the command will run and immediately exit.

If you need to run a program that requires user input, you can run the [.inline-code]kubectl exec[.inline-code] command using the [.inline-code]-i[.inline-code] and [.inline-code]-t[.inline-code] flags:

 $ kubectl exec -i -t <pod name> -- <command>

Where:

  • [.inline-code]-i[.inline-code] connects your terminal to the standard input of the command’s process.
  • [.inline-code]-t[.inline-code] wraps the connection in a pseudo-TTY providing an enhanced terminal-like interface.

For example, to launch the NodeJS runtime in a Pod with the [.inline-code]node[.inline-code] command, you can run the following [.inline-code]kubectl[.inline-code] command:

 $ kubectl exec -it nodejs-pod -- node

This works exactly like running interactive commands in Docker, which you can learn more about by reading our article on how to run a Bash shell in Docker.

[#start-a-shell-session-in-a-container] Starting an interactive shell session in a Pod's container [#start-a-shell-session-in-a-container]

Often, it’s useful to start an interactive shell session instead of running a one-off command, for situations where you need to perform multiple manual actions or debug a container.

Most of the time you will want to simply run [.inline-code]bash[.inline-code], as it has pretty good odds of being defined in the PATH environment variable and provides a better experience then the [.inline-code]sh[.inline-code] shell.

To start an interactive shell session with Bash, you can use the following command:

 $ kubectl exec -it <pod> -- bash

[#list-available-shells] Finding the list of available shells [#list-available-shells]

If the [.inline-code]bash[.inline-code] command is not directly available in the PATH of the container, you can try one of the following popular shell paths instead:

  • /bin/bash
  • /bin/sh
  • /bin/zsh
  • /bin/ash

If none of these paths work, you may want to perform a search in folders like [.inline-code]/usr/bin[.inline-code], which can be automated using the following command:

 $ kubectl exec web-0 -- find /bin /usr/bin -name "*sh"

This command will search in the [.inline-code]/bin[.inline-code] and [.inline-code]/usr/bin[.inline-code] for anything ending with [.inline-code]sh[.inline-code]. Some of these might not be shells, but most of the shells end with "sh". If you don’t have [.inline-code]find[.inline-code] you can use [.inline-code]ls[.inline-code] to manually go through them (combined with a local [.inline-code]grep[.inline-code]) to get a similar result.

[#run-commands-in-a-specific-container] Executing a command in a Pod with multiple containers [#run-commands-in-a-specific-container]

By default, [.inline-code]kubectl exec[.inline-code] will execute the specified command in the first container listed in the YAML Pod spec file.

To execute a command in a specific container instead, you can use the [.inline-code]-c[.inline-code] flag followed by the container’s name:

 $ kubectl exec -it <pod> -c <container> -- <command>

For example:

 $ kubectl exec -it web-0 -c monitor -- bash

This command will execute the [.inline-code]bash[.inline-code] command within the container named [.inline-code]monitor[.inline-code], that runs within the Pod named [.inline-code]web-0[.inline-code].

Note that to discover the names of the containers running within a Pod, you can either manually inspect the Pod's YAML file or use the [.inline-code]kubectl get pods[.inline-code] command as follows:

 $ kubectl get pods web-0 -o jsonpath='{.spec.containers[*].name}'

[#run-commands-using-kubernetes-resources] Executing a command in a Pod via a connected Kubernetes resource [#run-commands-using-kubernetes-resources]

By default, the [.inline-code]kubectl exec[.inline-code] command assumes that the specified resource a command should be executed on is a Pod.

To execute a command on another resource, such as a Deployment, a Statefulset or a Service, you can use the following syntax:

 $ kubectl exec [-it] <resource>/<name> -- <command>

Where:

  • [.inline-code]resource[.inline-code] is the type of the resource (e.g. [.inline-code]deployment[.inline-code], [.inline-code]service[.inline-code]).
  • [.inline-code]name[.inline-code] is the name of the resource.
  • [.inline-code]command[.inline-code] is the command to execute on the Pod managed by that resource.

For example:

 $ kubectl exec -it deployment/nginx -- bash

This command will execute the [.inline-code]bash[.inline-code] utility in interactive mode in the first container of the first Pod managed by the [.inline-code]nginx[.inline-code] Deployment.

[#run-commands-using-a-yaml-file] Executing a command in a Pod using a YAML manifest [#run-commands-using-a-yaml-file]

Another way to execute a command in a Pod is to use the YAML manifest the Pod or the Deployment was created from.

To achieve this, you can use the [.inline-code]-f[.inline-code] flag (short for [.inline-code]--filename[.inline-code]) as follows:

 $ kubectl exec -f <file> -- <command>

Where:

  • [.inline-code]file[.inline-code] is the relative or absolute path to the YAML manifest file.
  • [.inline-code]command[.inline-code] is the command to execute on the Pod declared in this file.

For example:

 $ kubectl exec -f deployment.yaml -- ls /

This command will read the [.inline-code]deployment.yaml[.inline-code] file and execute the [.inline-code]ls /[.inline-code] command in the first Pod of the replicaset of the Deployment specified in that file.

Note that, if the YAML manifest contains more than one Deployment / Pod, the [.inline-code]kubectl exec[.inline-code] command will fail.

[#handle-limited-user-privileges] Handling limited user privileges [#handle-limited-user-privileges]

When running a command using [.inline-code]kubectl exec[.inline-code], the command will run using the same user that the container is running as. In Kubernetes (and Docker) you can specify any number as the user ID and the container will run as that user, even if no user was ever created with the ID. This is often used as a security feature where Pods will run using one of these non-existing users (typically User ID 1000/1001) providing very little access inside the container.

Sometimes you require higher privileges, and some commands even require root access to run. Unfortunately, you can’t directly execute a command as a separate user, but there are a few things you can do (depending on what’s possible per situation).

[#run-commands-as-root] Running a Pod as root [#run-commands-as-root]

To run a Pod as root, you can add the [.inline-code]runAsUser[.inline-code] option to the [.inline-code]securityContext[.inline-code] field and set it to the user ID of the root user, which is 0.

https://docs.google.com/document/d/1Pd87rIwF_bRGFXITdA5hIWpDZmuN1oRu9imcwn1Pbz4/edit

 apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  securityContext:
    runAsUser: 0
  containers:
  - name: nginx
    image: nginx:latest

Applying this will cause the containers within the Pod file to run as root, allowing you to now execute the command as the root user.

Note that you can’t directly edit the security context of a running Pod, so you will either have to edit the deployment if you have one, or edit the Pod file locally and delete then redeploy the changes.

Also note that this option might not work if your security policy in the cluster prevents running Pods as root.