Kubernetes 1.8 kube-scheduler的源码分析

简介: 很长时间没有写文章,一直在啃kubernetes文档,本来立志一定要读完所有的文档。还有它的最佳实践openshift的文档。但目前为止,我并没有读完kubernetes的文档。当前,我们有需求需要客制化kubernetes的调度函数,所以开始研究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()

  1. 创建NewSchedulerServer和启动调度服务;
  2. componentconfig.KubeSchedulerConfiguration{}定义了kube-scheduler的参数信息;

启动程序:plugin/cmd/kube-scheduler/app/server.go Run()

  1. 创建apiserver客户端–通过REST方式访问APIserver提供的API服务,用来watch
    pod和node,并调用apiserver bind接口完成node和pod的Bind操作;
  2. 创建eventBroadcaster对象–发送event到logging函数,发送event到eventSink,同时EventRecorder记录event source;
  3. 创建sharedInformerFactory对象,并创建PodInformer对象,PodInformer用于watch/list non-terminal pods并缓存;
  4. 创建schedulerConfigurator对象
  5. 创建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 ;
  6. 运行http Server–提供必要的性能分析(profiling)和性能指标度量(Metrics),Handler包括/debug/pprof/和/metrics;
  7. 启动informerFactory.start() ,开始运行Informer,进行缓存;
  8. 运行调度程序;
  9. 创建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

本文转自kubernetes中文社区-Kubernetes 1.8 kube-scheduler的源码分析

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
Kubernetes 容器
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
222 0
|
12月前
|
Kubernetes 算法 调度
Kubernetes的灵魂核心:kube-scheduler
本文介绍了Kubernetes中关键组件kube-scheduler的工作原理,详细解释了其通过预选和优选过程为Pod选择合适节点的机制,并提供了一个简化的Python示例来模拟这一过程,帮助读者更好地理解和管理Kubernetes集群。
|
Kubernetes 容器
Kubernetes高可用集群二进制部署(四)部署kubectl和kube-controller-manager、kube-scheduler
Kubernetes高可用集群二进制部署(四)部署kubectl和kube-controller-manager、kube-scheduler
|
Kubernetes 算法 调度
|
存储 Kubernetes 安全
【K8s源码品读】010:Phase 1 - kube-scheduler - Informer是如何保存数据的
了解Informer在发现资源变化后,是怎么处理的
105 0
|
Kubernetes 容器
【K8s源码品读】009:Phase 1 - kube-scheduler - Informer监听资源变化
了解Informer是如何从kube-apiserver监听资源变化的情况
218 0
|
缓存 分布式计算 资源调度
kubernetes 【调度和驱逐】【2】kube-scheduler调度器
kubernetes 【调度和驱逐】【2】kube-scheduler调度器
kubernetes 【调度和驱逐】【2】kube-scheduler调度器
|
缓存 Prometheus 监控
Kubernetes容器监控原理与源码分析(一)——API与数据来源
## 前言 本系列主要基于v1.24.0版本的Kubelet部分源代码,进行Kubernetes中容器监控的底层原理介绍与代码分析。 ## Kubelet中的监控API 在Kubelet Server提供的监控API中,大致可以分为两类:stats(统计数据)和metrics(指标数据)。从命名和实际作用来看,前者提供了粗粒度的基础监控能力,目前用于各种内置组件;而后者用于持久化地进行细粒度的容器
1112 2
Kubernetes容器监控原理与源码分析(一)——API与数据来源
|
Kubernetes 调度 容器

推荐镜像

更多