-
Notifications
You must be signed in to change notification settings - Fork 3.7k
扩展Kubernetes Scheduler By 泽东
转载请注明出处即可。 所使用源码k8s源码为release-1.18
如果对K8s的Scheduler不是很了解,可以先看下Kubernetes Scheduler简介这篇文章
Scheduler的扩展有两种方式,一种是修改Scheduler的源码,编写调度和绑定两个过程的插件。然后将插件注册。
还有一种是通过Extender来进行扩展, 可以通过http请求调用自己编写的extender项目来处理自定义调度。
第一种的话,需要修改源码,但可以修改的阶段比较灵活,而第二种方法,处理的阶段比较宽泛。 本文主要是通过第二种方式, 首先先构建k8s集群,然后构建一个用于模拟调度扩展的项目。
需要准备一个多节点的k8s集群,如果手上没有现成的测试集群或者云服务。那么可以看kubernetes部署-基于vmware+centos7虚拟机3个节点这篇文章来搭建一个简单的集群。 需要注意的是,本文使用的k8s版本为1.18,之前那篇文章上为1.17.4,需要升级。
需要多节点的原因如上图,仅仅是一个节点的话,也就无需考虑到底放到哪里了^_^
。
所使用的环境为 Go 1.14版本,并且配置了go mod。通过go mod来安装相关包。框架主要使用gin,toml, k8s client等。
# 配置到.bash_profile中或者.zshrc中
export GOPROXY="https://goproxy.cn"
export GO111MODULE=on
因为考虑到大部分开发都在用Java,所以在这里多啰嗦几句。 首先创建一个项目文件夹 scheduler-extender 然后进入到文件夹内部执行go mod init scheduler-extender创建go.mod 然后安装相关的包
go get github.com/BurntSushi/toml
go get github.com/gin-gonic/gin
go get k8s.io/kube-scheduler
如果安装成功的话 go.mod如下图所示,当然版本可能会有所不同
然后简单封装下https://gitee.com/VincentWang/scheduler-extender,具体extender实现都在这个项目中
项目封装后,在看下需要如何接收与返回参数,然后在考虑如果编写相关逻辑。 首先看下HTTPExtender的 send 方法, 发现使用的json格式,并且args参数会序列化成json后发送到自定义的extender服务中。
send方法有四处调用,分别对应着,
- Filter: 在调度过程中,过滤掉不部署pod的node
- Preempt: 在资源不足时候,抢占低优先级的pod资源,优先保证高优先级pod运行
- Prioritize: node排序,在资源充足时,选择"最佳"的node
- Bind: 绑定阶段
在看下具体调用send方法的地方,这里只看下Filter 其实在上面的四个扩展都有对应的传参和返回值(ExtenderArgs是filter和prioritize两个阶段在共用),在scheduler-extender项目实现时,需要分别进行处理。
我这里的nodes环境如下。
ip | host | node role |
---|---|---|
192.168.179.137 | ceph1 | master |
192.168.179.138 | ceph2 | master |
192.168.179.139 | ceph3 | master |
然后我们来模拟实现一个调度,filter阶段过滤掉cehp3,prioritize阶段, cehp1的优先级高于ceph2, preempt, bind先不实现。实现后,理论上部署的pod会部署到ceph1中。
具体实现逻辑完成后,在ceph3中进行项目部署,生产环境中可以部署到k8s中。
首先先关注下如何进行配置,才能让Scheduler去调用scheduler-extender。
首先不稳当的api版本才会用internal
。
const (
// APIVersionInternal may be used if you are registering a type that should not
// be considered stable or serialized - it is a convention only and has no
// special behavior in this package.
APIVersionInternal = "__internal"
)
然后在看下v1alpha2版本的api,发现也可以使用Extenders配置。
保存以下配置到sched.yaml中, 这个配置可以参考源码中的KubeSchedulerConfiguration struct,在官网没有搜索到具体的配置项,注意不要使用json的配置,k8s的这个api解析json有些bug。
apiVersion: kubescheduler.config.k8s.io/v1alpha2
kind: KubeSchedulerConfiguration
extenders:
- urlPrefix: http://192.168.179.139/scheduler-extender
filterVerb: filter
prioritizeVerb: prioritize
nodeCacheCapable: true
enableHttps: false
weight: 100000
leaderElection:
leaderElect: true
clientConnection:
kubeconfig: /etc/kubernetes/scheduler.conf
并将sched.yaml 放到/etc/kubernetesf中,然后修改/etc/kubernetes/manifests下的kube-scheduler.yaml文件
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-scheduler
tier: control-plane
name: kube-scheduler
namespace: kube-system
spec:
containers:
- command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --leader-elect=true
- --config=/etc/kubernetes/sched.yaml
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.2
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10259
scheme: HTTPS
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-scheduler
resources:
requests:
cpu: 100m
volumeMounts:
- mountPath: /etc/kubernetes/scheduler.conf
name: kubeconfig
readOnly: true
- mountPath: /etc/kubernetes/sched.yaml
name: schedconfig
readOnly: true
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/scheduler.conf
type: FileOrCreate
name: kubeconfig
- hostPath:
path: /etc/kubernetes/sched.yaml
type: FileOrCreate
name: schedconfig
status: {}
主要增加了--config配置以及通过hostPath挂载sched.yaml 可以查看下是否存在配置错误
k logs -f kube-scheduler-ceph1 -n kube-system
修改过kube-scheduler.yaml后,k8s会自动重启pod,但是需要将3个节点的配置都修改下才行
。
上面小节的步骤都完成后,尝试部署一个简单的pod。 在执行指令前,一定要确保scheduler-extender程序是在运行的。
kubectl run kubia --image=luksa/kubia --port=8080
在执行后, 查看po的状态
kubectl get po
这里我们也可以看到scheduler-extender也存在对应的请求
最后看下是否部署到了ceph1节点
kubectl descibe po kubia
DONE,大功告成。
小傅哥(微信:fustack),公众号:bugstack虫洞栈
| bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
🌏 知识星球:码农会锁
实战项目:「DDD+RPC分布式抽奖系统
」、专属小册、问题解答、简历指导、架构图稿、视频课程
🐲 头条
-
💥
🎁 Lottery 抽奖系统
- 基于领域驱动设计的四层架构的互联网分布式开发实践 -
小傅哥的《重学 Java 设计模式》
- 全书彩印、重绘类图、添加内容 -
⭐小傅哥的《Java 面经手册》
- 全书5章29节,417页11.5万字,完稿&发版 -
小傅哥的《手撸 Spring》
- 通过带着读者手写简化版 Spring 框架,了解 Spring 核心原理 -
🌈小傅哥的《SpringBoot 中间件设计和开发》
- 小册16个中间件开发30个代码库
⛳ 目录
💋 精选
🐾 友链
建立本开源项目的初衷是基于个人学习与工作中对 Java 相关技术栈的总结记录,在这里也希望能帮助一些在学习 Java 过程中遇到问题的小伙伴,如果您需要转载本仓库的一些文章到自己的博客,请按照以下格式注明出处,谢谢合作。
作者:小傅哥
链接:https://bugstack.cn
来源:bugstack虫洞栈
2021年10月24日,小傅哥
的文章全部开源到代码库 CodeGuide
中,与同好同行,一起进步,共同维护。
这里我提供 3 种方式:
-
提出
Issue
:在 Issue 中指出你觉得需要改进/完善的地方(能够独立解决的话,可以在提出 Issue 后再提交PR
)。 -
处理
Issue
: 帮忙处理一些待处理的Issue
。 -
提交
PR
: 对于错别字/笔误这类问题可以直接提交PR
,无需提交Issue
确认。
详细参考:CodeGuide 贡献指南 - 非常感谢你的支持,这里会留下你的足迹
- 加群交流 本群的宗旨是给大家提供一个良好的技术学习交流平台,所以杜绝一切广告!由于微信群人满 100 之后无法加入,请扫描下方二维码先添加作者 “小傅哥” 微信(fustack),备注:加群。
- 公众号(bugstack虫洞栈) - 沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。
感谢以下人员对本仓库做出的贡献或者对小傅哥的赞赏,当然不仅仅只有这些贡献者,这里就不一一列举了。如果你希望被添加到这个名单中,并且提交过 Issue 或者 PR,请与我联系。