作者: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/