View Source Bonny.Server.Scheduler behaviour (bonny v1.4.0)

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"
    conn = Bonny.Config.conn()

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

GpuScheduler.start_link()

Summary

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.

Selects the best node for the current pod.

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.

Callbacks

@callback conn() :: K8s.Conn.t()
@callback 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.

@callback name() :: binary()

Name of the scheduler.

@callback nodes(K8s.Conn.t()) :: {:ok, Enumerable.t()} | {:error, any()}

List of nodes available to this scheduler.

Default implementation is all nodes in cluster.

Link to this callback

select_node_for_pod(map, list)

View Source
@callback 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.

Functions

@spec bind(K8s.Conn.t(), map(), map()) :: {:ok, map()} | {:error, atom()}

Binds a pod to a node

Link to this function

field_selector(scheduler_name)

View Source
@spec field_selector(binary()) :: binary()

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

@spec nodes(K8s.Conn.t()) :: {:ok, [map()]} | {:error, any()}

Returns a list of all nodes in the cluster.

Link to this function

reconcile(scheduler, pod)

View Source
@spec reconcile(module(), map()) :: :ok