bonny v0.4.1 Bonny.Server.Scheduler behaviour

Kubernetes custom scheduler interface. Built on top of Reconciler.

The only function that needs to be implemented is select_node_for_pod/2. All others defined by behaviour have default implementations.

Examples

Will schedule each unschedule pod with spec.schedulerName=cheap-node to a node with a label cheap=true. nodes is a stream that can be lazily filtered:

defmodule CheapNodeScheduler do
  use Bonny.Server.Scheduler, name: "cheap-node"

  @impl Bonny.Server.Scheduler
  def select_node_for_pod(_pod, nodes) do
    nodes
    |> Stream.filter(fn(node) ->
      is_cheap = K8s.Resource.label(node, "cheap")
      is_cheap == "true"
    end)
    |> Enum.take(1)
    |> List.first
  end
end

CheapNodeScheduler.start_link()

Will schedule each unschedule pod with spec.schedulerName=random-node to a random node:

defmodule RandomNodeScheduler do
  use Bonny.Server.Scheduler, name: "random-node"

  @impl Bonny.Server.Scheduler
  def select_node_for_pod(_pod, nodes) do
    Enum.random(nodes)
  end
end

RandomNodeScheduler.start_link()

Override nodes/0 default implementation (pods/0 can be overridden too). Schedules pod on a random GPU node:

defmodule GpuScheduler do
  use Bonny.Server.Scheduler, name: "gpu-node"

  @impl Bonny.Server.Scheduler
  def select_node_for_pod(_pod, nodes) do
    Enum.random(nodes)
  end

  @impl Bonny.Server.Scheduler
  def nodes() do
    label = "my.label.on.gpu.instances"
    cluster = Bonny.Config.cluster_name()

    op = K8s.Client.list("v1", :nodes)
    K8s.Client.stream(op, cluster, params: %{labelSelector: label})
  end
end

GpuScheduler.start_link()

Link to this section Summary

Functions

Binds a pod to a node

Kubernetes API fieldSelector value for unbound pods waiting on the given scheduler.

Returns a list of all nodes in the cluster.

Returns a list of pods for the given field_selector.

Callbacks

Field selector for selecting unscheduled pods waiting to be scheduled by this scheduler.

Name of the scheduler.

List of nodes available to this scheduler.

List of unscheduled pods awaiting this scheduler.

Selects the best node for the current pod.

Link to this section Functions

Link to this function

bind(pod, node)
bind(map(), map()) :: {:ok, map()} | {:error, atom()}

Binds a pod to a node

Link to this function

field_selector(scheduler_name)
field_selector(binary()) :: binary()

Kubernetes API fieldSelector value for unbound pods waiting on the given scheduler.

Link to this function

nodes()
nodes() :: {:ok, [map()]} | {:error, any()}

Returns a list of all nodes in the cluster.

Link to this function

pods(module)
pods(module()) :: {:ok, [map()]} | {:error, any()}

Returns a list of pods for the given field_selector.

Link to this section Callbacks

Link to this callback

field_selector()
field_selector() :: binary()

Field selector for selecting unscheduled pods waiting to be scheduled by this scheduler.

Default implementation is all unscheduled pods assigned to this scheduler.

Link to this callback

name()
name() :: binary()

Name of the scheduler.

Link to this callback

nodes()
nodes() :: {:ok, Enumerable.t()} | {:error, any()}

List of nodes available to this scheduler.

Default implementation is all nodes in cluster.

Link to this callback

pods()
pods() :: {:ok, Enumerable.t()} | {:error, any()}

List of unscheduled pods awaiting this scheduler.

Default implementation is all unscheduled pods specifying this scheduler in spec.schedulerName.

Link to this callback

select_node_for_pod(map, list)
select_node_for_pod(map(), [map()]) :: map()

Selects the best node for the current pod.

Takes the current unscheduled pod and a Stream of nodes. pod is provided in the event that taints or affinities would need to be respected by the scheduler.

Returns the node to schedule on.