使用kube-scheduler-simulator演示在真实集群中的K8s调度程序

2022-11-28 17:33:28 浏览数 (1)

作者:Takuma Kawai

客座博文最初由 Takuma Kawai 在Miraxia 博客[1]上发表

前一篇文章[2]中,我写了如何用kube-scheduler-simulator[3]开发自己的调度程序。如果你可以实现你的新调度程序,你可能想在一个真实的集群中尝试一下。

在本文中,我描述了如何将一个调度器,移植到一个真实的集群中,这个调度器实现是为与 kube-scheduler-simulator 一起工作而设计的,并通过使用 kube-scheduler-simulator 的前端部分,演示了新调度器和默认调度器之间的区别。

如何将调度程序部署到真正的集群中?

官方文档“配置多个调度程序[4]”包含了如何将调度程序部署到集群的说明。从这篇文章中我们可以了解到,即使思考调度器,这听起来也很特别,但与其他控制器没有什么不同。这方面最重要的事实是:调度程序是一个可执行的命令。

如果你在 kube-scheduler-simulator 树中开发了一个新的调度器,就像我在上一篇文章中描述的那样,它一定是一个 golang 包。现在,要在真正集群中评估调度程序,必须用 main()包装它。

作为可执行命令构建 minisched

作为一个有趣的例子,我再次选择minisched[5](initial-random-scheduler 版本)。它为我们提供了这个实验的明确结果,换句话说,它的行为与默认的调度程序完全不同。

下面是 minisched 一个简单的 main()的例子。

代码语言:javascript复制
package main

import (
 "context"
 "flag"
 "k8s.io/apiserver/pkg/server"
 "k8s.io/client-go/informers"
 "k8s.io/client-go/kubernetes"
 "k8s.io/client-go/tools/clientcmd"
 "k8s.io/klog/v2"
 "example.com/kube-random-scheduler/minisched"
)

func main() {
 kubeconfig := flag.String("kubeconfig", "", "kubeconfig config file")
 flag.Parse()

 config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
 if err != nil {
  klog.Fatalf("Error building kubeconfig: %s", err.Error())
 }

 clientset, err := kubernetes.NewForConfig(config)
 if err != nil {
  klog.Fatalf("Error building example clientset: %s", err.Error())
 }

 ctx, cancel := context.WithCancel(context.Background())
 defer cancel()
 go func() {
  stopCh := server.SetupSignalHandler()
  <-stopCh
  cancel()
 }()
 informerFactory := informers.NewSharedInformerFactory(clientset, 0)
 sched := minisched.New(clientset, informerFactory)
 informerFactory.Start(ctx.Done())
 informerFactory.WaitForCacheSync(ctx.Done())
 sched.Run(ctx)
}

构建这个,你需要以下文件结构。

代码语言:javascript复制
kube-random-scheduler
├── main.go
└── minisched

此树中的 minisched 应该从 mini-kube-scheduler 复制,你可能需要修改 minisched/initialize.go 中的导入 URL,如下所示。

代码语言:javascript复制
Patch license: MIT (same as mini-kube-scheduler)

--- a/minisched/initialize.go
    b/minisched/initialize.go
@@ -1,7  1,7 @@
 package minisched

 import (
-       "github.com/sanposhiho/mini-kube-scheduler/minisched/queue"
        "example.com/kube-random-scheduler/minisched/queue"
        "k8s.io/client-go/informers"
        clientset "k8s.io/client-go/kubernetes"
 )

现在,你可以通过以下命令来构建它。

代码语言:javascript复制
$ go mod init example.com/kube-random-scheduler
$ go mod tidy
$ CGO_ENABLED=0 go build -v -o kube-random-scheduler main.go

一旦构建了可执行文件,就可以按照官方文档《配置多个调度程序》中的说明来部署它。注意,你应该删除示例清单中的 livenessProbe 和 readinessProbe,因为上面的 main()没有 healthz 实现。

通过 kube-scheduler-simulator 显现调度行为

我一直想将我的调度程序实现的底层行为可视化。由于仪表板[6]不足以达到这个目的,我决定使用 kube-scheduler-simulator 的前端部分。

kube-scheduler-simulator 由三个容器组成,simulator-server、simulator-etcd 和 simulator-frontend。simulator-frontend 是一个 Nuxt.js 应用程序,通过 REST API 与 simulator-server 通信。这些 API 与 K8s 实现兼容,因此我们可以将 simulator-frontend 连接到真实集群中的 kube-apiserver。这使我们能够看见真实集群中调度程序的底层行为。

首先,你需要为集群的 kube-apiserver 添加--cors-allowed-origins 选项。

代码语言:javascript复制
--- kube-apiserver.yaml.orig    2022-09-01 18:06:34.983636661  0900
    kube-apiserver.yaml 2022-09-01 18:06:12.459666678  0900
@@ -13,6  13,7 @@
   containers:
   - command:
     - kube-apiserver
     - --cors-allowed-origins=http://*
     - --advertise-address=192.168.1.51
     - --allow-privileged=true
     - --anonymous-auth=True

然后,在运行 kube-scheduler-simulator 的同一台主机上启动 kubectl 代理。

代码语言:javascript复制
simulator-pc$ docker-compose up -d simulator-frontend
simulator-pc$ kubectl proxy

最后,在运行 web 浏览器的主机上创建到 kube-scheduler-simulator 和 kubectl 代理的隧道。

代码语言:javascript复制
frontend-pc$ ssh -L 3000:localhost:3000 -L 3131:localhost:8001 simulator-pc

如果你成功地完成了,你可以在浏览器中查看随机调度的有趣结果,pod 被随机分配到节点。

总结

  • 调度程序以单个可执行命令的形式开发
  • 你可以使用 kube-scheduler-simulator 作为真实集群的可视化工具

参考资料

[1]

Miraxia 博客: https://www.miraxia.com/en/engineers-blog/demonstrating-your-k8s-scheduler-with-kube-scheduler-simulator-in-a-real-cluster/

[2]

前一篇文章: https://www.cncf.io/blog/2022/08/24/writing-your-own-scheduler-with-kube-scheduler-simulator/

[3]

kube-scheduler-simulator: https://github.com/kubernetes-sigs/kube-scheduler-simulator

[4]

配置多个调度程序: https://kubernetes.io/docs/tasks/extend-kubernetes/configure-multiple-schedulers/

[5]

minisched: https://github.com/sanposhiho/mini-kube-scheduler/tree/initial-random-scheduler/minisched

[6]

仪表板: https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

0 人点赞