k8s scheduler

Posted by [Kohn] on Monday, February 26, 2024
Last Modified on Tuesday, February 27, 2024
本文阅读量

1 scheduling framework

当前k8s的调度器使用的是scheduling framework

https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/ 调度器定义了一些列的hook点, 插件可以自行扩展

2 新的调度特性

Pod Scheduling Readiness

pod在创建后, 可以定义schedulingGates, 调度器如果发现pod的spec包含了schedulingGates, 就不进行调度, pod状态为SchedulingGated

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  schedulingGates:
  - name: example.com/foo
  - name: example.com/bar
  containers:
  - name: pause
    image: registry.k8s.io/pause:3.6

知道外部将schedulingGates移除后调度器才开始调度, 类似finalizer.

Pod Overhead

可以先定义一个RuntimeClass

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata-fc
handler: kata-fc
overhead:
  podFixed:
    memory: "120Mi"
    cpu: "250m"

然后创建pod时指定runtimeClassName:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  runtimeClassName: kata-fc
  ...

admission controller会将RuntimeClass中定义的量设置到pod.spec.overhead上

调度器调度时会把这个pod的资源需求理解成requests+overhead

cgroup配置时:

  • cpu.cfs_quota_us: limit+overhead
  • memory.limit_in_bytes memory: limit+overhead
  • cpu.shares: requests+overhead

3 scheduler调度策略配置

Scheduling Policies

早期通过配置predicates and priorities来修改调度策略, 1.23版本的k8s之后不再支持, 而是使用Scheduler Configuration

Scheduler Configuration

https://kubernetes.io/docs/reference/scheduling/config/

Scheduler Configuration基于Scheduling Framework定义的hook点, 允许用户自行配置.

自定义插件时, 一般拉取k8s的scheduler代码库, 然后基于这份代码库开发自己 的插件. 当然也可以完全自己开发, 本质上其实就是监听pod然后设置 pod的.spec.nodeName.

开发完成后, 可以直接将原生的调度器的镜像替换掉并修改对应的配置文件, 也可以多个调度器同时存在, 然后通过schedulerName区分 https://kubernetes.io/docs/reference/scheduling/config/#multiple-profiles

方法:在配置文件中定义好不同的schedulerName对应什么插件配置, 创建pod时 配置好需要使用哪个scheduler来调度(通过.spec.schedulerName)scheduling framework在调度pod时会查看.spec.schedulerName, 然后从配置文件中读取对 应的插件配置, 如果读取不到, 就不会调度.

4 scheduler中的几个队列

https://github.com/kubernetes/community/blob/f03b6d5692bd979f07dd472e7b6836b2dad0fd9b/contributors/devel/sig-scheduling/scheduler_queues.md

  • activeQ: 根据pod优先级排序的一个heap, 调用循环会不断从中取pod进行调度
  • unschedulableQ: 暂时不调度的队列
  • podBackoffQ: 根据backoff time(决定多久之后重试)排序的一个heap, schedule或者binding失败后挪到这个队列, 然后等待时机挪到activeQ里
    • backoff time根据失败次数不断指数增加, 一直到最大值(默认10s)