Kubernetes
Shell Scripting
Command Execution
DevOps
Containers

Executing multiple commands or from a shell script in a kubernetes pod

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Running multiple commands inside a Kubernetes pod is a common need for debugging, one-off maintenance, and operational diagnostics. The most frequent mistake is treating kubectl exec like a full shell session without explicitly invoking a shell. kubectl exec runs exactly the command you pass; shell operators like &&, ;, pipes, and redirects only work when interpreted by a shell process.

There are three reliable approaches:

  1. pass a shell command string (sh -c or bash -c),
  2. copy and run a script inside the container,
  3. package scripts in the image or mount them via ConfigMap for repeatable operations.

Choosing the right pattern depends on whether you need ad hoc troubleshooting or reproducible automation.

Core Sections

1. Execute chained commands with sh -c

If the container has /bin/sh, this is the quickest approach.

bash
kubectl exec -n appns my-pod -- sh -c 'echo "start"; whoami; ls -la /tmp'

Use && when later commands should only run on success:

bash
kubectl exec -n appns my-pod -- sh -c 'cd /data && ./migrate.sh && ./verify.sh'

For multi-container pods, specify container name:

bash
kubectl exec -n appns my-pod -c worker -- sh -c 'env | sort'

If shell features are missing in distroless images, this method will fail. In that case, run binary commands directly or use a debug sidecar/container.

2. Copy and run a script for complex sequences

For anything beyond a short chain, scripts are clearer and safer.

bash
1cat > run-checks.sh <<'SH'
2#!/bin/sh
3set -eu
4
5echo "hostname: $(hostname)"
6id
7ls /app
8/app/bin/healthcheck
9SH
10
11kubectl cp run-checks.sh appns/my-pod:/tmp/run-checks.sh
12kubectl exec -n appns my-pod -- sh -c 'chmod +x /tmp/run-checks.sh && /tmp/run-checks.sh'

Benefits:

  • versionable logic,
  • easier local testing,
  • less quoting complexity.

For recurring jobs, avoid manual copy-exec and move script into image or mounted ConfigMap.

3. Use ConfigMap-mounted scripts for reproducible ops

A good operational pattern is storing maintenance scripts as ConfigMap data and mounting into pods.

yaml
1apiVersion: v1
2kind: ConfigMap
3metadata:
4  name: ops-scripts
5  namespace: appns
6data:
7  cleanup.sh: |
8    #!/bin/sh
9    set -eu
10    echo "Cleaning temp files"
11    rm -rf /tmp/*

Mount and execute:

bash
kubectl exec -n appns my-pod -- sh -c 'chmod +x /opt/scripts/cleanup.sh && /opt/scripts/cleanup.sh'

This is safer than ad hoc manual commands because it is auditable and repeatable across environments.

4. Security and safety practices

  • Use least-privilege RBAC for pods/exec.
  • Prefer read-only debug commands in production unless change is approved.
  • Log executed operations in incident timeline.
  • For recurring administrative tasks, use Job or CronJob instead of repeated manual exec.

Common Pitfalls

  • Forgetting sh -c and wondering why && or pipes do not work with kubectl exec.
  • Running complex quoted commands inline and introducing escaping mistakes that change behavior.
  • Executing in wrong container of a multi-container pod because -c was omitted.
  • Relying on shell presence in minimal/distroless images where /bin/sh is unavailable.
  • Using manual exec operations as permanent process instead of codifying them in Jobs/scripts.

Summary

To run multiple commands in a Kubernetes pod, use kubectl exec ... -- sh -c '...' for quick tasks, and use scripts for complex or repeatable workflows. For production-grade reliability, package or mount scripts and control execution through RBAC and automation rather than ad hoc shelling. That balance gives both operational speed and auditability.

For production teams, command execution policy matters as much as syntax. A helpful pattern is defining an operational "command catalog" in version control. Instead of engineers improvising shell chains during incidents, provide vetted scripts for common tasks such as log collection, certificate checks, cache inspection, and feature-flag toggles. Then expose those scripts through approved runbooks and RBAC-limited service accounts. This reduces quoting mistakes and prevents accidental destructive commands from being run interactively in critical namespaces.

Another practical improvement is to use ephemeral debug containers (kubectl debug) for investigation rather than modifying app containers directly. Debug containers can include shell tools (curl, jq, dig, netstat) missing from lean production images. That keeps application images minimal and secure while still enabling deep troubleshooting when needed. If your platform supports session recording, enable it for exec operations in sensitive clusters so post-incident reviews can reconstruct exactly what commands were run and why.


Course illustration
Course illustration

All Rights Reserved.