Kubernetes 1.8 kube-scheduler的源码分析

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 很长时间没有写文章,一直在啃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的源码分析

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
Kubernetes 容器
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
132 0
|
2月前
|
Kubernetes 算法 调度
Kubernetes的灵魂核心:kube-scheduler
本文介绍了Kubernetes中关键组件kube-scheduler的工作原理,详细解释了其通过预选和优选过程为Pod选择合适节点的机制,并提供了一个简化的Python示例来模拟这一过程,帮助读者更好地理解和管理Kubernetes集群。
|
6月前
|
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在发现资源变化后,是怎么处理的
55 0
|
Kubernetes 容器
【K8s源码品读】009:Phase 1 - kube-scheduler - Informer监听资源变化
了解Informer是如何从kube-apiserver监听资源变化的情况
103 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(指标数据)。从命名和实际作用来看,前者提供了粗粒度的基础监控能力,目前用于各种内置组件;而后者用于持久化地进行细粒度的容器
878 2
Kubernetes容器监控原理与源码分析(一)——API与数据来源
|
Kubernetes 调度 容器