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
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 runcreates 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
kubectlsends aPOST /api/v1/namespaces/default/podsrequest to the API server.- The API server validates the request and creates a Pod object in etcd.
- The scheduler assigns the pod to a node with available resources.
- The kubelet on that node pulls the image and starts the container.
kubectl get podsshowsRunningwithin 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=Neverflag 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 runcreates an imperative Pod with no controller attached.- Use
--restart=Neverfor ephemeral tasks,--commandto override entrypoint, and--dry-run=clientto 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=Neverfor one-shot jobs — the defaultAlwaysrestart policy causes pods to restart infinitely after the container exits. - Using
kubectl runin CI/CD pipelines where declarative manifests are required for reproducibility and GitOps workflows. - Specifying
--commandincorrectly: the syntax must be--command -- <binary> <args>, not--command '<binary> <args>'. - Omitting the
--separator betweenkubectl runflags and the command arguments, which leads to flag parsing errors.
Variations
- Use
kubectl create deployment nginx --image=nginxto create a Deployment that self-heals and supports rolling updates — preferred for production workloads. - Use
kubectl runwith--dry-run=client -o yaml > pod.yamlthen edit the YAML file before applying withkubectl apply -f— combines speed of imperative creation with reproducibility. - 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 3600on 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 runis an imperative command that creates a Pod directly without a controller like Deployment.- The only required argument is the pod name and
--imageflag; all other flags are optional. - Always use
--restart=Neverfor ephemeral pods, otherwise the container will restart on exit. - Use
--dry-run=client -o yamlto generate a Pod YAML manifest that you can version-control and edit. kubectl runis ideal for debugging, testing images, and quick experiments — avoid it for production workloads where self-healing is needed.- The
--commandflag syntax requires--command -- <binary>with the--separator to distinguish flags from command arguments.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.