Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Run a pod with kubectl run

Run a pod with kubectl run — kubernetes. Practical steps to create pods imperatively with kubectl run. Covers core concepts, syntax, hands-on exercise, options comparison, and troubleshooting. Connects workload creation to larger Kubernetes workflows.

Focus: run a pod with kubectl run

Sponsored

You've deployed applications to a cluster, but you're still writing multi-line YAML files for a simple test. That overhead blocks rapid experimentation. kubectl run cuts the ceremony — one command creates a pod right now. It's the Kubernetes equivalent of docker run; essential for debugging, quick demos, and bootstrap testing without version-controlled manifests.

The problem this lesson solves

Kubernetes orchestrates declaratively — you write a pod spec as YAML, then kubectl apply -f. That's correct for production, but it's slow when you need to:

  • Test a container image immediately.
  • Verify cluster networking or DNS inside a temporary pod.
  • Generate a skeleton YAML file to edit later.
  • Launch a one-off data-processing task without building a Deployment.

kubectl run gives you an imperative lever: you describe what you want ("run nginx") and the API server creates a Pod resource instantly. No kind: Pod declaration needed. This is the fastest way to get a container running on a Kubernetes cluster.

Core concept / mental model

Think of kubectl run as the Kubernetes equivalent of docker container run — but the result is a scheduled Pod, not a standalone container. The API server creates a Pod resource that includes:

  • A spec.containers array with your image and command.
  • Optional labels, restart policy, ports, environment variables, and more.
  • Automatic scheduling to a healthy node.

Pro tip: kubectl run creates a Pod, not a Deployment. The pod has no controller backing it — if it dies, it stays dead. Use it for ephemeral workloads only.

The command is imperative because you're issuing an action ("create this") rather than declaring a desired state ("ensure this exists"). Contrast with kubectl apply which is declarative.

How it works step by step

1. Basic syntax

kubectl run <pod-name> --image=<container-image> [flags]

The only required argument is a pod name (must be unique within the namespace) and --image. Everything else — command, ports, environment — is optional.

2. What happens inside the control plane

  1. kubectl sends a POST /api/v1/namespaces/default/pods request to the API server.
  2. The API server validates the request and creates a Pod object in etcd.
  3. The scheduler assigns the pod to a node with available resources.
  4. The kubelet on that node pulls the image and starts the container.
  5. kubectl get pods shows Running within seconds.

3. Adding common flags

Flag Purpose Example
--command Override the container ENTRYPOINT --command -- /bin/sh -c '...'
--port Expose a container port (metadata) --port=8080
--env Set environment variables --env=APP_ENV=staging
--labels Attach key=value labels --labels=app=debug,task=test
--restart Pod restart policy (Never, OnFailure, Always) --restart=Never
--dry-run=client Print YAML without creating the pod --dry-run=client -o yaml

The --restart=Never flag is critical when you want a single-run pod that won't be rescheduled by a controller.

Hands-on walkthrough

Create a simple pod

kubectl run nginx-pod --image=nginx:alpine

Expected output:

pod/nginx-pod created

Verify:

kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          10s

Create a pod with a custom command

Sometimes you need to run a shell script at startup, not the default entrypoint:

kubectl run debug-pod \
  --image=busybox:1.28.4 \
  --restart=Never \
  --command -- /bin/sh -c 'echo "Hello from Kubernetes" && sleep 3600'

Expected output:

pod/debug-pod created

Check logs:

kubectl logs debug-pod
Hello from Kubernetes

Use --dry-run to generate YAML without creating anything

This is the bridge between imperative and declarative workflows:

kubectl run dry-pod --image=redis:7 --port=6379 --dry-run=client -o yaml

Output (trimmed):

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: dry-pod
  name: dry-pod
spec:
  containers:
  - image: redis:7
    name: dry-pod
    ports:
    - containerPort: 6379
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Save it to a file: kubectl run ... --dry-run=client -o yaml > pod.yaml. Now you can edit and commit it.

Compare options / when to choose what

Approach Use case Pros Cons
kubectl run Quick test, debug pod, one-off task Fast, minimal typing, inline flags No self-healing, not reproducible
kubectl apply -f pod.yaml Declarative, version-controlled pods Reproducible, can be reviewed in Git Slower for ad-hoc experiments
kubectl create deployment Creating a Deployment (not Pod) Built-in controller, rollout updates More flags; different resource type

When to choose kubectl run: local development, debugging a new image, testing network policies, or when you need a temporary sidecar for diagnostics. Avoid it in CI/CD pipelines that should be idempotent and declarative.

Troubleshooting & edge cases

"Pod image pull backoff" or "ImagePullBackOff"

Symptom: kubectl get pods shows ImagePullBackOff.

Cause: The container image doesn't exist, the tag is wrong, or you lack pull credentials.

Fix: - Verify the image name and tag: kubectl run test --image=nginx:wrongtag will fail. - For private registries, add --image-pull-secrets or configure a default service account.

Pod stays in "Pending" state

Symptom: Pod won't become Running.

Cause: Not enough CPU/memory on any node, or a node selector that doesn't match.

Fix:

kubectl describe pod pending-pod

Look for events like FailedScheduling. Add resources or remove node constraints.

Pod crashes immediately (CrashLoopBackOff)

Symptom: CrashLoopBackOff after a few seconds.

Cause: The container's main process exits. For example, busybox without a sleep command runs and exits immediately.

Fix: - Use --command -- /bin/sh -c 'while true; do echo alive; sleep 5; done'. - Or use a long-running image like nginx or alpine/socat.

You forget --restart=Never and the pod restarts forever

kubectl run defaults restartPolicy: Always. If your container exits (e.g., a batch job), the kubelet restart it endlessly. Add --restart=Never or --restart=OnFailure for one-shot workloads.

What you learned & what's next

You now know how to run a pod with kubectl run — from a simple kubectl run nginx to generating YAML with --dry-run=client -o yaml. The key takeaways:

  • kubectl run creates an imperative Pod with no controller attached.
  • Use --restart=Never for ephemeral tasks, --command to override entrypoint, and --dry-run=client to produce reusable YAML.
  • Pods created this way are ideal for debugging, testing images, and quick experiments — but not for production workloads.

Next lesson: Learn how to edit a live pod with kubectl edit pod — imperative changes without destroying the resource. You'll combine kubectl run with kubectl edit to fix configurations on the fly.

Now open your terminal and create your first debugging pod with kubectl run debug --image=alpine:3.18 --command -- sleep 3600. Confirm it's running with kubectl get pods.

Practice recap

Create two pods in your minikube or kind cluster: kubectl run webserver --image=nginx:alpine and kubectl run batch --image=busybox:1.28.4 --restart=Never --command -- /bin/sh -c 'echo done; sleep 2'. Verify the webserver pod stays Running and the batch pod shows Completed. Then generate a YAML file from the batch pod using --dry-run=client -o yaml and review its structure.

Common mistakes

  • Forgetting --restart=Never for one-shot jobs — the default Always restart policy causes pods to restart infinitely after the container exits.
  • Using kubectl run in CI/CD pipelines where declarative manifests are required for reproducibility and GitOps workflows.
  • Specifying --command incorrectly: the syntax must be --command -- <binary> <args>, not --command '<binary> <args>'.
  • Omitting the -- separator between kubectl run flags and the command arguments, which leads to flag parsing errors.

Variations

  1. Use kubectl create deployment nginx --image=nginx to create a Deployment that self-heals and supports rolling updates — preferred for production workloads.
  2. Use kubectl run with --dry-run=client -o yaml > pod.yaml then edit the YAML file before applying with kubectl apply -f — combines speed of imperative creation with reproducibility.
  3. In scripting, use kubectl run --generator=run-pod/v1 (deprecated in 1.18+) or rely on the default generator which creates Pods directly.

Real-world use cases

  • Debugging a failing application by running a temporary diagnostic pod with kubectl run debug --image=nicolaka/netshoot --command -- sleep 3600 on the same node.
  • Quickly testing a new container image in a staging cluster before writing the full Deployment YAML and adding health probes.
  • Launching a one-off data transformation job (e.g., kubectl run transform --image=python:3.10-slim --restart=Never --command -- python transform.py) without creating a Job resource.

Key takeaways

  • kubectl run is an imperative command that creates a Pod directly without a controller like Deployment.
  • The only required argument is the pod name and --image flag; all other flags are optional.
  • Always use --restart=Never for ephemeral pods, otherwise the container will restart on exit.
  • Use --dry-run=client -o yaml to generate a Pod YAML manifest that you can version-control and edit.
  • kubectl run is ideal for debugging, testing images, and quick experiments — avoid it for production workloads where self-healing is needed.
  • The --command flag syntax requires --command -- <binary> with the -- separator to distinguish flags from command arguments.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.