Kubernetes 1.8 kube-scheduler的源码分析
很长时间没有写文章,一直在啃kubernetes文档,本来立志一定要读完所有的文档。还有它的最佳实践openshift的文档。但目前为止,我并没有读完kubernetes的文档。当前,我们有需求需要客制化kubernetes的调度函数,所以开始研究kube-scheduler的代码。
kube-scheduler的代码的风格和逻辑对于Gophers并不陌生。权威的作者这样评价kubernetes的源码:代码简洁,设计巧妙,程序逻辑分解得恰到好处,每个组件各司其职,从而化繁为简,主体流程清晰直观,犹如行云流水,一气呵成。(虽然v.1.8.1已经和书中v1.3的代码发生了不小的改变。)总之,kubernetes的源码值得反复阅读学习,主要是每个版本代码都不一样,变化一直在进行中。
kubernetes tag v.1.8.1
kube-scheduler的代码路径为:plugin/
入口程序:plugin/cmd/kube-scheduler/scheduler.go main()
- 创建NewSchedulerServer和启动调度服务;
- componentconfig.KubeSchedulerConfiguration{}定义了kube-scheduler的参数信息;
启动程序:plugin/cmd/kube-scheduler/app/server.go Run()
- 创建apiserver客户端–通过REST方式访问APIserver提供的API服务,用来watch
pod和node,并调用apiserver bind接口完成node和pod的Bind操作; - 创建eventBroadcaster对象–发送event到logging函数,发送event到eventSink,同时EventRecorder记录event source;
- 创建sharedInformerFactory对象,并创建PodInformer对象,PodInformer用于watch/list non-terminal pods并缓存;
- 创建schedulerConfigurator对象
- 创建genericScheduler对象(接口Scheduler) ,genericScheduler对象的创建过程:
a. 创建schedulerConfigurator对象,它包含ConfigFactory对象(接口Configurator) plugin/cmd/kube-scheduler/app/configurator.gob. 调用schedulerConfigurator对象的create()方法创建Scheduler对象;genericScheduler对象是由ConfigFactory对象(Configurator是接口)的createFromProvider()方法创建的plugin/cmd/kube-scheduler/pkg/scheduler/factory/factory.goc. 创建Scheduler需要如下Informer参数:nodeInformer、pvInformer、pvcInformer、rcInformer、rsInformer、statefulsetInformer、serviceInformer ; - 运行http Server–提供必要的性能分析(profiling)和性能指标度量(Metrics),Handler包括/debug/pprof/和/metrics;
- 启动informerFactory.start() ,开始运行Informer,进行缓存;
- 运行调度程序;
- 创建Leaderelection对象,并启动leaderElector.Run() — 创建resourcelock对一些资源上锁。同时,值得一提,controller-manager和kube-scheduler两个组件可以配置跟本机的APIServer通信,也可以不是。在高可用部署情况下,controller-manager和kube-scheduler两个组件,存在选举机制,为了保证选举成功,需要奇数节点部署组件,而当前工作组件只有一个,用于更新集群状态,并与其他节点组件同步信息。
SharedInformers模式设计同时用在k8s的”Controller”中,下面是一段关于SharedInformers模式设计的英文介绍:(摘自https://github.com/kubernetes/ … rs.md)
Use SharedInformers. SharedInformers provide hooks to receive notifications of adds, updates, and deletes for a particular resource. They also provide convenience functions for accessing shared caches and determining when a cache is primed.
SharedInformers提供勾子机制,获得特定资源的添加、更新、删除通知。并提供函数更新缓存,启动执行。简而言之kube-scheduler的”informer”负责:watch/list non-terminal pods, 缓存,并从podQueue中获得NextPod,执行调度;
调度程序:plugin/pkg/scheduler/scheduler.go Run()
1. 等待缓存更新完成;
2. 运行调度流程;
调度流程:plugin/pkg/scheduler/scheduler.go scheduleOne()
1.从podQueue缓存中获得一个Pod;
2. 获得一个suggestedHost,如果获得失败将调用抢占逻辑sched.preempt(),记录算法延迟的度量metrics.SchedulingAlgorithmLatency;–获得suggestedHost是同步操作;
3. Pod将标注为assumedPod;此时Pod并没有被成功调度;
4. 绑定(bind) Pod到suggestedHost,记录调度延迟的度量metrics.E2eSchedulingLatency;–绑定操作是异步操作;
调度逻辑:plugin/pkg/scheduler/scheduler.go Schedule()
1. 根据调度策略算法确定一个suggestedHost;
调度算法函数:
1. 接口类plugin/pkg/scheduler/algorithm/scheduler_interface.go, 默认使用plugin/pkg/scheduler/core/generic_scheduler.go
2. 调度算法函数支持plugin模式plugin/pkg/scheduler/algorithmprovider/plugins.go,scheduler的commandLine参数AlgorithmProvider可以指定调度算法函数;默认使用defaultProvider, defaultPredicates(), defaultPriorities() plugin/pkg/scheduler/algorithmprovider/defaults/default.go;同时,scheduler的commandLine参数PolicyConfigFile,可以加载自定义的调度策略文件。如:openshift中,/etc/origin/master/scheduler.json定义了调度策略文件。(参考信息:https://docs.openshift.com/con … .html)
3. FitPredicates:k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates
4. PrioritiesFunc:k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities
5. 调度流程plugin/pkg/scheduler/core/generic_scheduler.go schedule(),调度流程图如下:(摘自kubernetes调度详解:http://dockone.io/article/2885)
绑定逻辑:plugin/pkg/scheduler/scheduler.go bind()
1. 绑定接口Binder plugin/pkg/scheduler/scheduler.go
2. 更新cache中assumedPod为expired SchedulerCache.FinishBinding(),接口/实现: plugin/pkg/scheduler/schedulercache/interface.go;plugin/pkg/scheduler/schedulercache/cache.go;
3. 记录绑定延迟的度量metrics.BindingLatency;
4. 记录绑定事件;
阅读代码的建议:
1. 读文档,k8s的文档写得非常好,如果文档没有提及的,读代码;
2. 要带着问题探索性的阅读代码,比如:error handling是如何处理的?如果pod没有被正确的调度会发生什么?
调度的性能:
k8s SIG Scale Group对k8s调度服务进行了性能测试,得到的数据:1000 pods跑在1000个节点上,调度延迟为23s,调度程序的吞吐量是51 pods/秒;
https://docs.google.com/presen … _2866
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
kubernetes RBAC实战 kubernetes 用户角色访问控制,dashboard访问,kubectl配置生成
kubernetes RBAC实战 环境准备 先用kubeadm安装好kubernetes集群,[包地址在此](https://market.aliyun.com/products/56014009/cmxz022571.html#sku=yuncode1657100000) 好用又方便,服务周到,童叟无欺 本文目的,让名为devuser的用户只能有权限访问特定namespace下的pod 命令行kubectl访问 安装cfssl 此工具生成证书非常方便, pem证书与crt证书,编码一致可直接使用 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 chmod +x cfssl_linux-amd64 mv cfssl_linux-amd64 /bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod +x cfssljson_linux-amd64 mv cfssljson_linux-amd64 /bin/cfssljson wget https://...
- 下一篇
Kubernetes的service mesh – 第四部分:通过流量切换持续部署
概述除了服务发现、顶层指标和TLS,linkerd 也提供一种称为dtabs的强大的路由语言,它可以更改应用拓扑中的请求,甚至是单独某个请求的请求路径。本文中,我们会给您展示如何使用linkerd作为服务网格对新代码进行CI/CD管道最后一步的蓝绿发布。 注意:这是关于Linkerd、Kubernetes和service mesh的系列文章其中一篇,其余部分包括: 1.Top-line service metrics 2.Pods are great, until they’re not 3.Encrypting all the things 4.Continuous deployment via traffic shifting(本文) 5.Dogfood environments, ingress, and edge routing 6.Staging microservices without the tears 7.Distributed tracing made easy 8.Linkerd as an ingress controller 9.gRPC for fun an...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题