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的源码分析

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
6月前
|
Kubernetes 容器
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
使用Kubeadm部署K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题
|
6月前
|
Kubernetes 算法 调度
|
6月前
|
存储 Kubernetes 安全
【K8s源码品读】010:Phase 1 - kube-scheduler - Informer是如何保存数据的
了解Informer在发现资源变化后,是怎么处理的
33 0
|
6月前
|
Kubernetes 容器
【K8s源码品读】009:Phase 1 - kube-scheduler - Informer监听资源变化
了解Informer是如何从kube-apiserver监听资源变化的情况
48 0
|
6月前
|
Kubernetes 算法 调度
|
缓存 分布式计算 资源调度
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(指标数据)。从命名和实际作用来看,前者提供了粗粒度的基础监控能力,目前用于各种内置组件;而后者用于持久化地进行细粒度的容器
748 2
Kubernetes容器监控原理与源码分析(一)——API与数据来源
|
Kubernetes 调度 容器
|
Kubernetes 容器
Kubernetes Client-go Informer 源码分析
几乎所有的Controller manager 和CRD Controller 都会使用Client-go 的Informer 函数,这样通过Watch 或者Get List 可以获取对应的Object,下面我们从源码分析角度来看一下Client go Informer 的机制。
4511 0
|
Kubernetes 网络协议 数据格式
kubeadm源码分析(kubernetes离线安装包,三步安装)
kubeadm源码分析 说句实在话,kubeadm的代码写的真心一般,质量不是很高。 几个关键点来先说一下kubeadm干的几个核心的事: kubeadm 生成证书在/etc/kubernetes/pki目录下 kubeadm 生成static pod yaml配置,全部在/etc/kuberne.
1730 0