Project reference ↗

Spot Rescheduler tried to move workloads from one group of Kubernetes machines to another, commonly from on-demand AWS instances onto available Spot capacity. That could leave the original machines empty enough for a separate autoscaler to remove. It was useful for a particular cost-control workflow, but it did not create the replacement capacity itself. The project is unmaintained, and any replacement needs to account for the disruption caused by moving running workloads.

Current guidance

The deprecated stable/k8s-spot-rescheduler chart points to pusher/k8s-spot-rescheduler. Its upstream README explicitly marks the repository unmaintained and seeking new owners. This tool moved pods from one labeled node group to another, especially from on-demand capacity to Spot capacity; it was not the component provisioning those nodes.

Before replacing it, identify why workloads remain on the expensive node group and which scheduler or node-provisioning policy should own consolidation. Moving a pod generally involves disruption, so account for PodDisruptionBudgets, local storage, topology constraints and workloads that cannot safely restart. A nominally cheaper target node is not useful if it cannot satisfy those constraints.

Treat consolidation and interruption handling as separate requirements. Spot notice handling cannot guarantee that every pod finishes before a node disappears, and voluntary rescheduling should not race another component’s drain operation. Evaluate the capabilities of the actual cluster autoscaler or provisioning system, then test a bounded set of disposable workloads. Preserve availability and rollback visibility rather than adopting a similarly named controller without checking its current maintenance and eviction behavior.

Historical upstream link check · 2026-10-09

The recorded upstream address responded successfully (HTTP 200) on 2026-10-09. GitHub confirms that helm/charts is archived: this is a historical chart distribution, not evidence that the application itself is retired. Link availability does not certify the historical installation instructions or current security support.

Source for this check ↗

Website availability is separate from project, chart and image support. Use the current guidance and primary sources on this page to assess the distribution.

The original record

Historical Kubedex content

Preserved for context. Commands, versions, prices and results below reflect the original research.

K8s Spot rescheduler is a tool that tries to reduce load on a set of Kubernetes nodes. It was designed with the purpose of moving Pods scheduled on AWS on-demand instances to AWS spot instances to allow the on-demand instances to be safely scaled down (By the Cluster Autoscaler).

In reality the rescheduler can be used to remove load from any group of nodes onto a different group of nodes. They just need to be labelled appropriately.

For example, it could also be used to allow controller nodes to take up slack while new nodes are being scaled up, and then rescheduling those pods when the new capacity becomes available, thus reducing the load on the controllers once again.

Attribution

This project was inspired by the Critical Pod Rescheduler and takes portions of code from both the Critical Pod Rescheduler and the Cluster Autoscaler.

Motivation

AWS spot instances are a great way to reduce the cost of your infrastructure running costs. They do however come with a significant drawback; at any point, the spot price for the instances you are using could rise above your bid and your instances will be terminated. To solve this problem, you can use an AutoScaling group backed by on-demand instances and managed by the Cluster Autoscaler to take up the slack when spot instances are removed from your cluster.

The problem however, comes when the spot price drops and you are given new spot instances back into your cluster. At this point you are left with empty spot instances and full, expensive on-demand instances.

By tainting the on-demand instances with the Kubernetes PreferNoSchedule taint, we can ensure that, if at any point the scheduler needs to choose between spot and on-demand instances, it will choose the preferred spot instances to schedule the new Pods onto.

However, the scheduler won’t reschedule Pods that are already running on on-demand instances, blocking them from being scaled down. At this point, the K8s Spot Rescheduler is required to start the process of moving Pods from the on-demand instances back onto the spot instances.

Usage

Deploy to Kubernetes

A docker image is available at quay.io/pusher/k8s-spot-rescheduler. These images are currently built on pushes to master. Releases will be tagged as and when releases are made.

Sample Kubernetes manifests are available in the deploy folder.

To deploy in clusters using RBAC, please apply all of the manifests (Deployment, ClusterRole, ClusterRoleBinding and ServiceAccount) in the deploy folder but uncomment the serviceAccountName in the deployment

Requirements

For the K8s Spot Rescheduler to process nodes as expected; you will need identifying labels which can be passed to the program to allow it to distinguish which nodes it should consider as on-demand and which it should consider as spot instances.

For instance you could add labels node-role.kubernetes.io/worker and node-role.kubernetes.io/spot-worker to your on-demand and spot instances respectively.

You should also add the PreferNoSchedule taint to your on-demand instances to ensure that the scheduler prefers spot instances when making it’s scheduling decisions.

 

Operating logic

 

The rescheduler logic roughly follows the below:

  1. Gets a list of on-demand and spot nodes and their respective Pods
  • Builds a map of nodeInfo structs
    • Add node to struct
    • Add pods for that node to struct
    • Add requested and free CPU fields to struct
  • Map these structs based on whether they are on-demand or spot instances.
  • Sort on-demand instances by least requested CPU
  • Sort spot instances by most free CPU
  1. Iterate through each on-demand node and try to drain it
  • Iterate through each pod
    • Determine if a spot node has space for the pod
    • Add the pod to the prospective spot node
    • Move onto next node if no spot node space available
  • Drain the node
    • Iterate through pods and evict them in turn
      • Evict pod
      • Wait for deletion and reschedule
    • Cancel all further processing

This process is repeated every housekeeping-interval seconds.

The effect of this algorithm should be, that we take the emptiest nodes first and empty those before we empty a node which is busier, thus resulting in the highest number of ’empty’ nodes that can be removed from the cluster.

Sources & further reading

  1. Historical chart identity
  2. Pusher unmaintained notice
  3. AWS Spot interruption semantics
  4. Recovered historical source (Common Crawl index)

Spotted something that needs another look?

Help improve this page →