Open-Source Wikis

/

Kubernetes

/

Components

/

Scheduling framework

kubernetes/kubernetes

Scheduling framework

The framework is the contract between the scheduler core and its plugins. Everything in pkg/scheduler/framework/plugins/ implements one or more of these interfaces.

Extension points

Defined in pkg/scheduler/framework/interface.go:

Interface Called when Return
QueueSortPlugin Building the active queue Less function for QueuedPodInfo
PreEnqueuePlugin Before a pod enters the active queue Allow / hold
PreFilterPlugin Beginning of a scheduling cycle Compute per-pod state stored in CycleState
FilterPlugin For each candidate node Fit / Unschedulable / UnschedulableAndUnresolvable
PostFilterPlugin When no node fit Optional preemption attempt
PreScorePlugin After Filter, before Score Compute scoring inputs
ScorePlugin For each fitting node 0–100 score
ScoreExtensions.NormalizeScore After Score Optional rescale
ReservePlugin Best node chosen Reserve / Unreserve hooks
PermitPlugin After Reserve Allow / Deny / Wait
PreBindPlugin Before Bind Mutate cluster state required for bind (e.g. PVC binding)
BindPlugin The actual bind Patch Pod.Spec.NodeName (default)
PostBindPlugin After Bind Notification only

A plugin can implement any subset of these. PreFilter and PreScore exist so plugins can compute expensive per-pod state once and reuse it through CycleState.

CycleState

pkg/scheduler/framework/cycle_state.go is a thread-safe map keyed by string. Plugins use it to pass data between extension points within a single scheduling cycle. Each plugin stores its own typed value (e.g. interpodaffinityState, volumebinding.stateData).

CycleState.Clone() is called when the scheduler runs Filter against multiple nodes in parallel — each goroutine gets a snapshot.

NodeInfo and the snapshot

pkg/scheduler/framework/types.go defines NodeInfo, the scheduler's per-node summary (allocated resources, running pods, taints, image set, …). The cache in pkg/scheduler/backend/cache keeps a NodeInfo per node and refreshes incrementally on informer events.

Each scheduling cycle starts by snapshotting the cache (scheduler.Cache.UpdateSnapshot). Filter and Score run against the snapshot, so the inputs are stable for the duration of the cycle.

Parallelism

pkg/scheduler/framework/parallelize provides bounded-parallel iteration. Filter runs across nodes via Until(ctx, len(nodes), func(i int){...}). The default parallelism is 16, configurable via KubeSchedulerConfiguration.Parallelism.

Events that wake unschedulable pods

When a Filter plugin returns Unschedulable, the pod ends up in the unschedulable map. To know when to retry, each plugin declares its EventsToRegister — a list of (GVK, ActionType) pairs that affect its decision. The queue framework subscribes to those events and re-queues only the affected pods.

For example, the noderesources plugin registers on Node Add, Node Update, and Pod Delete. The volumebinding plugin registers on PV Add, PVC Add/Update, StorageClass Add, and so on.

This is what keeps a 5,000-node cluster from re-evaluating every pending pod for every irrelevant cluster change.

Profiles and weights

A profile (KubeSchedulerProfile in pkg/scheduler/apis/config) selects which plugins are enabled per extension point and assigns Score weights. The same binary can run multiple profiles concurrently; pods select via Pod.Spec.SchedulerName.

Adding a plugin: minimum viable example

  1. Implement one of the interfaces:

    type Plugin struct{ handle framework.Handle }
    
    func (p *Plugin) Name() string { return "MyPlugin" }
    func (p *Plugin) Filter(ctx context.Context, state *framework.CycleState,
        pod *v1.Pod, info fwk.NodeInfo) *fwk.Status {
        // ...
    }
  2. Provide a constructor:

    func New(_ context.Context, _ runtime.Object, h framework.Handle) (framework.Plugin, error) {
        return &Plugin{handle: h}, nil
    }
  3. Register in pkg/scheduler/framework/plugins/registry.go (or use an out-of-tree scheduler binary that registers via app.WithPlugin).

  4. Enable in a profile:

    profiles:
      - schedulerName: default-scheduler
        plugins:
          filter:
            enabled:
              - name: MyPlugin
  5. Test with pkg/scheduler/testing/ helpers — MakeNode, MakePod, RegisterFilterPlugin, etc.

Key source files

File Purpose
pkg/scheduler/framework/interface.go Plugin interfaces
pkg/scheduler/framework/types.go NodeInfo, PodInfo, QueuedPodInfo
pkg/scheduler/framework/cycle_state.go Per-cycle state map
pkg/scheduler/framework/runtime/framework.go Plugin orchestrator
pkg/scheduler/framework/parallelize/parallelism.go Bounded-parallel iterator
pkg/scheduler/framework/preemption/preemption.go Preemption helper
pkg/scheduler/backend/queue/scheduling_queue.go The four-band queue, event subscription

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Scheduling framework – Kubernetes wiki | Factory