Stage 5 · Platform
Workloads & Scheduling
Custom Schedulers & Extenders
Scheduler framework, plugins, and writing a scheduler plugin.
Scheduler Framework
The Scheduler Framework (introduced in Kubernetes 1.15, GA in 1.19) lets you customize the scheduler through in-process Go plugins. Plugins are registered at specific extension points in the scheduling pipeline. This is faster and more powerful than HTTP extenders.
Extension Points
The scheduler pipeline has 8 extension points. Each runs at a specific phase and can reject, score, or modify pods. Understanding these extension points helps you choose the right one for your use case.
| Extension Point | When | Use Case |
|---|---|---|
| PreFilter | Before filtering | Pre-compute data for Filter phase |
| Filter | During filtering | Reject nodes that don't meet criteria |
| PostFilter | After filtering fails | Preemption — evict pods to make room |
| PreScore | Before scoring | Pre-compute data for Score phase |
| Score | During scoring | Rank nodes by custom criteria |
| Reserve | After binding | Reserve resources on the node |
| Permit | After reserve | Approve or deny binding |
| PostBind | After binding | Cleanup or notification |
Writing a Custom Plugin
A practical example: a plugin that ensures only pods with specific labels are scheduled on GPU nodes. The Filter plugin checks node labels; the Score plugin prefers nodes with more available GPUs.
Plugins are registered in the scheduler configuration file under plugins. Each plugin is listed under the extension points it implements. A single plugin can implement multiple extension points.
HTTP Extenders
HTTP extenders are external processes that the scheduler calls via HTTP during the scheduling pipeline. They are simpler to implement than in-process plugins but add network latency. Use them when the plugin logic lives in a separate service.
extenders:
- urlPrefix: "https://extender.example.com"
filterVerb: "filter"
prioritizeVerb: "prioritize"
bindVerb: "bind"
preemptVerb: "preempt"
nodeCacheCapable: true
managedResources:
- name: custom.io/gpu
ignoreWithoutName: false
ignorable: falsenodeCacheCapable means the extender caches node information locally, reducing API calls. ignorable: false means the scheduler waits for the extender even if it times out. Set ignorable: true for optional extenders.
Multi-Scheduler
Kubernetes supports multiple schedulers. You can run the default scheduler alongside custom schedulers. Pods specify which scheduler to use via schedulerName. This lets you partition workloads — e.g., one scheduler for batch jobs, another for latency-sensitive services.
apiVersion: v1
kind: Pod
metadata:
name: batch-job
spec:
schedulerName: batch-scheduler # Use custom scheduler
containers:
- name: worker
image: my-worker:1.0If schedulerName doesn't match any running scheduler, the pod stays Pending. Ensure the custom scheduler is running and watching for pods with its name.
Testing Plugins
Test scheduler plugins using the scheduler testing framework. You can create fake nodes and pods, run the scheduling cycle, and verify the output. Integration tests use envtest for a real API server.
Set --v=4 on the scheduler to see detailed scoring. The output shows each plugin's score for each node. Use kubectl describe pod to see why a pod was not scheduled — the Events section shows filter and score results.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.