Kubectl run command with nodeSelector and tolerations
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
kubectl run is useful for creating a quick one-off Pod, but it does not expose dedicated flags for every field in the Pod spec. If you need nodeSelector and tolerations, the practical choices are either to use --overrides with inline JSON or to generate YAML and apply a proper manifest.
Understand What nodeSelector and Tolerations Do
nodeSelector restricts scheduling to nodes with matching labels. Tolerations do not select nodes by themselves. They only allow a Pod to be scheduled onto nodes with matching taints.
In practice, that means:
- '
nodeSelectorsays where the Pod is allowed to go' - tolerations say which taints the Pod is willing to tolerate
You often need both when a special node pool is tainted and labeled.
Use kubectl run --overrides for a Quick Pod
For an ad hoc Pod, --overrides is the direct answer.
That creates a Pod named debug-shell scheduled only onto nodes labeled workload=batch, and only if it tolerates the dedicated=batch:NoSchedule taint.
Verify the Labels and Taints First
Before blaming kubectl run, confirm the target nodes actually match what you requested.
List labels:
Describe the target node to inspect taints:
If the label is missing or the taint value does not match, the Pod will stay Pending no matter how correct the command syntax is.
Use --dry-run to Generate YAML
Inline JSON works, but it becomes hard to read quickly. A cleaner workflow is to generate a Pod manifest and edit it.
Then add the scheduling fields:
Apply it with:
For anything beyond a quick one-off, this is easier to maintain than an inline JSON string.
Prefer a Manifest for Repeatable Work
kubectl run is convenient for experimentation, but repeatable operations should usually live in YAML checked into source control. That gives you a readable review path and avoids shell-escaping issues.
It also makes later upgrades easier if you want to switch from a Pod to a Job or Deployment with the same scheduling rules.
When nodeSelector Is Not Enough
nodeSelector only supports exact label matching. If you need richer scheduling rules, use node affinity instead.
Example:
That is a better fit when you need multiple allowed values or more complex logic.
Debug a Pending Pod Systematically
If the Pod remains Pending, inspect it directly:
Look at the scheduler events near the bottom. They usually tell you whether the issue is:
- no nodes matched the selector
- the Pod did not tolerate a taint
- there were insufficient resources
- another admission or policy rule blocked scheduling
Reading events is faster than guessing.
Common Pitfalls
Expecting tolerations to select nodes. They do not. They only allow placement on tainted nodes.
Using kubectl run without --restart=Never and then being surprised by generated controller behavior in older workflows.
Writing invalid JSON in --overrides. Shell quoting errors are common.
Forgetting to verify node labels and taints before creating the Pod.
Using nodeSelector when the scheduling rule really requires node affinity.
Summary
- '
kubectl rundoes not have dedicated flags fornodeSelectorand tolerations, so use--overridesor YAML.' - '
nodeSelectorchooses matching labels, while tolerations allow tainted nodes.' - Verify node labels and taints before debugging the command.
- For anything reusable, generate or write a manifest instead of relying on inline JSON.
- Check scheduler events with
kubectl describe podwhen the Pod stays Pending.

