使用 kube-scheduler-simulator 模拟 K8s 调度器环境

开源
在本文中,我将介绍如何借助 kube-scheduler-simulator 这个调度器模拟器来构建调度程序开发环境。

由于默认的 Kubernetes 调度器是高度可配置的,在很多情况下我们不需要编写任何代码来自定义调度行为。但是,想要了解调度器如何工作或者有更多二次开发需求的人员可能会尝试开发自己的调度器,在本文中,我将介绍如何借助 kube-scheduler-simulator 这个调度器模拟器来构建调度程序开发环境。

安装模拟器

首先 Clone 模拟器的代码:

$ git clone https://github.com/kubernetes-sigs/kube-scheduler-simulator
$ cd kube-scheduler-simulator

为 web 前端和模拟器服务端构建镜像,执行 make docker_build_and_up 命令即可:

图片

镜像构建完成后我们可以直接使用 docker-compose up 命令来启动模拟器:

图片

启动后我们可以直接在浏览器中通过 localhost:3000 来访问模拟器的 Web 页面,如下所示:

图片

页面上提供了新建多种资源的方法,比如我们可以点击 NEW NODE 按钮来新建一些节点:

图片

只需要点击 APPLY 按钮即可新增一个节点,我们这里新增了 5 个节点。然后用同样的方式点击 NEW POD 新建一个 Pod,就会模拟整个调度过程:

图片

新建的 Pod 被调度到了其中一个节点上:

图片

点击 Pod 的名称可以查看到该 Pod 的整个调度过程,包括 Filter 阶段、Score 阶段和最终打分结果。

图片

我们可以直接点击左上角的设置按钮来对调度器进行配置,实际上就是修改 KubeSchedulerConfiguration 对象:

图片

使用

我们了解了如果通过模拟器来了解 Pod 的调度,那么如果我们要开发一个新的调度器插件,那么又应该怎么结合模拟器来使用呢?

这里我们以 https://github.com/sanposhiho/mini-kube-scheduler 这个程序为例进行说明,这个调度器实现了随机决定 Pod 的 Node。

要让我们在模拟器中使用该调度器,需要执行以下一些过程:

  • 将mini-kube-scheduler/minisched (从分支 initial-random-scheduler)复制到kube-scheduler-simulator。
  • 修改kube-scheduler-simulator/scheduler/scheduler.go 文件来使用minisched。

修改 kube-scheduler-simulator/scheduler/scheduler.go 文件的内容如下所示,主要看 StartScheduler 函数的修改:

package scheduler
import (
"context"
"sigs.k8s.io/kube-scheduler-simulator/simulator/minisched"
"golang.org/x/xerrors"
v1 "k8s.io/api/core/v1"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/events"
"k8s.io/klog/v2"
v1beta2config "k8s.io/kube-scheduler/config/v1beta2"
"k8s.io/kubernetes/pkg/scheduler"
"k8s.io/kubernetes/pkg/scheduler/apis/config"
"k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
"k8s.io/kubernetes/pkg/scheduler/apis/config/v1beta2"
simulatorschedconfig "sigs.k8s.io/kube-scheduler-simulator/simulator/scheduler/config"
"sigs.k8s.io/kube-scheduler-simulator/simulator/scheduler/plugin"
)
// ......
// StartScheduler starts scheduler.
func (s *Service) StartScheduler(versionedcfg *v1beta2config.KubeSchedulerConfiguration) error {
clientSet := s.clientset
ctx, cancel := context.WithCancel(context.Background())

informerFactory := scheduler.NewInformerFactory(clientSet, 0)
evtBroadcaster := events.NewBroadcaster(&events.EventSinkImpl{
Interface: clientSet.EventsV1(),
})
evtBroadcaster.StartRecordingToSink(ctx.Done())
s.currentSchedulerCfg = versionedcfg.DeepCopy()
sched := minisched.New(
clientSet,
informerFactory,
)
informerFactory.Start(ctx.Done())
informerFactory.WaitForCacheSync(ctx.Done())
go sched.Run(ctx)
s.shutdownfn = cancel
return nil
}
// ......

将调度器改成 sched := minisched.New(clientSet informerFactory, ),也就是现在我们只使用 minisched 这个调度器了。

修改完成后重新编译项目:

$ make docker_build_and_up

编译完成后重新启动容器:

$ docker-compose up

启动后可以再次通过 localhost:3000 访问模拟器,现在我们的模拟器中只有 minisched 这一个调度算法了,我们可以新建几个 Pod 进行测试:

图片

现在就看不到之前调度器的几个阶段了,因为我们没有注册:

图片

比如我们将 minisched 调度器的调度算法从随机选择一个节点改成固定选择第一个节点,修改 kube-scheduler-simulator/simulator/minisched/minisched.go 文件的 scheduleOne 函数,如下所示:

图片

同样修改后重新编译、重新启动容器,然后重新访问模拟器的 Web 页面,现在我们新建的 Pod 可以发现始终都会调度到第一个 Node 节点去了。

图片

现在我们就可以根据需求去开发自己的调度器算法了,完全不需要一个真实的 K8s 集群。

责任编辑:姜华 来源: k8s技术圈
相关推荐

2023-08-07 08:10:46

2021-01-29 08:22:03

调度器Yarn架构

2021-11-29 08:48:00

K8S KubernetesAirflow

2022-04-22 13:32:01

K8s容器引擎架构

2023-11-29 09:29:48

Kuberneteskube

2023-11-06 07:16:22

WasmK8s模块

2022-06-14 07:56:15

Kubernetes存储架构K8S

2021-05-07 09:31:33

KindK8s Operator

2023-09-06 08:12:04

k8s云原生

2021-07-14 14:20:22

root命令Linux

2024-01-07 19:43:50

K8S节点

2021-08-05 07:28:26

K8sNFS ProvisiSubdir

2020-05-12 10:20:39

K8s kubernetes中间件

2022-09-05 08:26:29

Kubernetes标签

2023-08-03 08:36:30

Service服务架构

2023-05-25 21:38:30

2023-08-04 08:19:02

2021-12-31 08:43:45

插件KubeScheduler

2023-09-15 08:00:20

Ingress网关Istio

2019-09-25 07:17:42

KubernetesIstio测试
点赞
收藏

51CTO技术栈公众号