Skip to main content
This lesson explains how to manually schedule a Pod onto a specific node in Kubernetes. Use cases include clusters without a scheduler, situations where you don’t want to rely on the built-in scheduler, or when you need exact control over which node runs a Pod.

How the scheduler works (under the hood)

Every Pod has a nodeName 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 nodeName in the Pod manifest at creation time (simplest).
  • Create a Binding for 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 to node02:
Apply it:
If the target node exists and the Pod can be scheduled there, the Pod transitions from Pending to Running:
Important details:
  • nodeName can 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 without nodeName, 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:
POST the binding to the API at the path: /api/v1/namespaces/<namespace>/pods/<pod>/binding One convenient way to do this locally is with kubectl proxy and curl:
(Replace 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 a nodeName remain in Pending state until they are:
  • manually bound (via nodeName on creation or a Binding), 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 create Binding objects via RBAC.
  • When scripting binds via the API, use kubectl proxy for 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:
  1. Setting nodeName in the Pod manifest at creation time, or
  2. Creating and POSTing a Binding object for an already-created Pod.
Both approaches bypass (or mimic) the scheduler’s bind operation. Choose the one that fits your workflow, and ensure the actor performing the binding has the necessary RBAC permissions.

Watch Video

Practice Lab