How the scheduler works (under the hood)
Every Pod has anodeName field. By default, the nodeName field is not set in the Pod manifest you create. The Kubernetes scheduler watches for Pods that do not have nodeName set, selects a suitable node, and binds the Pod to that node. The scheduler’s bind operation creates a Binding object (v1 Binding) for the Pod, which results in the Pod’s nodeName being set and the Pod being scheduled onto the chosen node.
There are two manual ways to schedule a Pod:
- Set
nodeNamein the Pod manifest at creation time (simplest). - Create a
Bindingfor an already-created Pod (mimics what the scheduler does).
Option 1 — Set nodeName in the Pod manifest (creation time)
This is the simplest manual scheduling approach: specify the node you want the Pod to run on when creating the Pod. Example Pod manifest that pins the Pod tonode02:
Pending to Running:
nodeNamecan only be set at Pod creation time. It is effectively immutable and cannot be modified on an existing Pod.- Use this method when you know exactly which node should host the Pod and you can control the manifest used to create the Pod.
Option 2 — Create a Binding for an existing Pod
If a Pod was created withoutnodeName, you can bind it to a node by creating a Binding object and POSTing it to the Pod’s binding subresource. This is exactly what the scheduler does when it schedules a Pod.
Example Binding JSON that binds the Pod nginx in the default namespace to node02:
/api/v1/namespaces/<namespace>/pods/<pod>/binding
One convenient way to do this locally is with kubectl proxy and curl:
default, nginx, and node02 with your namespace, Pod name, and node name as needed.)
Manually creating a Binding requires RBAC permission to create the
binding subresource for the Pod. In many clusters, this capability is limited to controller accounts (for example, the scheduler); regular users may not have permission by default.Behavior when no scheduler is present
If there is no scheduler watching for unscheduled Pods, Pods without anodeName remain in Pending state until they are:
- manually bound (via
nodeNameon creation or aBinding), or - handled by a scheduler that is later started/installed.
Quick comparison (at-a-glance)
Best practices and tips
- Prefer higher-level primitives (Deployments, DaemonSets, StatefulSets) along with node selectors, node affinity, or taints/tolerations for scheduler-driven placement. Manual scheduling is useful in labs, debugging, or very specific control scenarios.
- For reproducible automation, generate manifests (with
nodeName) or control who can createBindingobjects via RBAC. - When scripting binds via the API, use
kubectl proxyfor local testing or interact directly with the API server using a properly-configured client certificate/token.
Summary
Manual scheduling in Kubernetes is achieved by either:- Setting
nodeNamein the Pod manifest at creation time, or - Creating and POSTing a
Bindingobject for an already-created Pod.
Links and references
- Kubernetes Scheduler Overview
- Pods — Assigning Pods to Nodes
- API Reference — Binding
- kubectl proxy documentation