2019独角兽企业重金招聘Python工程师标准>>>

Author: xidianwangtao@gmail.com

Kubernetes Node Controller源码分析之执行篇

更多关于kubernetes的深入文章,请看我csdn或者oschina的博客主页。

Node Controller的启动


if ctx.IsControllerEnabled(nodeControllerName) {// 解析得到Cluster CIDR, # clusterCIDR is CIDR Range for Pods in cluster._, clusterCIDR, err := net.ParseCIDR(s.ClusterCIDR)// 解析得到Service CIDR,# serviceCIDR is CIDR Range for Services in cluster._, serviceCIDR, err := net.ParseCIDR(s.ServiceCIDR)// 创建NodeController实例nodeController, err := nodecontroller.NewNodeController(sharedInformers.Core().V1().Pods(),sharedInformers.Core().V1().Nodes(),sharedInformers.Extensions().V1beta1().DaemonSets(),cloud,clientBuilder.ClientOrDie("node-controller"),s.PodEvictionTimeout.Duration,s.NodeEvictionRate,s.SecondaryNodeEvictionRate,s.LargeClusterSizeThreshold,s.UnhealthyZoneThreshold,s.NodeMonitorGracePeriod.Duration,s.NodeStartupGracePeriod.Duration,s.NodeMonitorPeriod.Duration,clusterCIDR,serviceCIDR,int(s.NodeCIDRMaskSize),s.AllocateNodeCIDRs,s.EnableTaintManager,utilfeature.DefaultFeatureGate.Enabled(features.TaintBasedEvictions),)// 执行Run方法启动该ControllernodeController.Run()// sleep一个随机时间,该时间大小为 “ControllerStartInterval + rand.Float64()*1.0*float64(ControllerStartInterval))”,其中ControllerStartInterval可以通过配置kube-controller-manager的"--controller-start-interval”参数指定。time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
} 

因此,很清晰地,关键就在以下两步:

  • nodeController, err := nodecontroller.NewNodeController创建NodeController实例。
  • nodeController.Run()执行Run方法启动该Controller。

NodeController的定义

在分析NodeController的原理之前,我们有必要先看看NodeController是如何定义的,其完整的定义如下:

type NodeController struct {allocateNodeCIDRs boolcloud             cloudprovider.InterfaceclusterCIDR       *net.IPNetserviceCIDR       *net.IPNetknownNodeSet      map[string]*v1.NodekubeClient        clientset.Interface// Method for easy mocking in unittest.lookupIP func(host string) ([]net.IP, error)// Value used if sync_nodes_status=False. NodeController will not proactively// sync node status in this case, but will monitor node status updated from kubelet. If// it doesn't receive update for this amount of time, it will start posting "NodeReady==// ConditionUnknown". The amount of time before which NodeController start evicting pods// is controlled via flag 'pod-eviction-timeout'.// Note: be cautious when changing the constant, it must work with nodeStatusUpdateFrequency// in kubelet. There are several constraints:// 1. nodeMonitorGracePeriod must be N times more than nodeStatusUpdateFrequency, where//    N means number of retries allowed for kubelet to post node status. It is pointless//    to make nodeMonitorGracePeriod be less than nodeStatusUpdateFrequency, since there//    will only be fresh values from Kubelet at an interval of nodeStatusUpdateFrequency.//    The constant must be less than podEvictionTimeout.// 2. nodeMonitorGracePeriod can't be too large for user experience - larger value takes//    longer for user to see up-to-date node status.nodeMonitorGracePeriod time.Duration// Value controlling NodeController monitoring period, i.e. how often does NodeController// check node status posted from kubelet. This value should be lower than nodeMonitorGracePeriod.// TODO: Change node status monitor to watch based.nodeMonitorPeriod time.Duration// Value used if sync_nodes_status=False, only for node startup. When node// is just created, e.g. cluster bootstrap or node creation, we give a longer grace period.nodeStartupGracePeriod time.Duration// per Node map storing last observed Status together with a local time when it was observed.// This timestamp is to be used instead of LastProbeTime stored in Condition. We do this// to aviod the problem with time skew across the cluster.nodeStatusMap map[string]nodeStatusDatanow           func() metav1.Time// Lock to access evictor workersevictorLock sync.Mutex// workers that evicts pods from unresponsive nodes.zonePodEvictor map[string]*RateLimitedTimedQueue// workers that are responsible for tainting nodes.zoneNotReadyOrUnreachableTainer map[string]*RateLimitedTimedQueuepodEvictionTimeout              time.Duration// The maximum duration before a pod evicted from a node can be forcefully terminated.maximumGracePeriod time.Durationrecorder           record.EventRecordernodeLister         corelisters.NodeListernodeInformerSynced cache.InformerSynceddaemonSetStore          extensionslisters.DaemonSetListerdaemonSetInformerSynced cache.InformerSyncedpodInformerSynced cache.InformerSynced// allocate/recycle CIDRs for node if allocateNodeCIDRs == truecidrAllocator CIDRAllocator// manages taintstaintManager *NoExecuteTaintManagerforcefullyDeletePod        func(*v1.Pod) errornodeExistsInCloudProvider  func(types.NodeName) (bool, error)computeZoneStateFunc       func(nodeConditions []*v1.NodeCondition) (int, zoneState)enterPartialDisruptionFunc func(nodeNum int) float32enterFullDisruptionFunc    func(nodeNum int) float32zoneStates                  map[string]zoneStateevictionLimiterQPS          float32secondaryEvictionLimiterQPS float32largeClusterThreshold       int32unhealthyZoneThreshold      float32// if set to true NodeController will start TaintManager that will evict Pods from// tainted nodes, if they're not tolerated.runTaintManager bool// if set to true NodeController will taint Nodes with 'TaintNodeNotReady' and 'TaintNodeUnreachable'// taints instead of evicting Pods itself.useTaintBasedEvictions bool
}

NodeController的行为配置

整个NodeController结构体非常复杂,包含30+项,我们将重点关注:

  • clusterCIDR - 通过--cluster-cidr来设置,表示CIDR Range for Pods in cluster。
  • serivceCIDR - 通过--service-cluster-ip-range来设置,表示CIDR Range for Services in cluster。
  • knownNodeSet - 用来记录NodeController observed节点的集合。
  • nodeMonitorGracePeriod - 通过--node-monitor-grace-period来设置,默认为40s,表示在标记某个Node为unhealthy前,允许40s内该Node unresponsive。
  • nodeMonitorPeriod - 通过--node-monitor-period来设置,默认为5s,表示在NodeController中同步NodeStatus的周期。
  • nodeStatusMap - 用来记录每个Node最近一次观察到的Status。
  • zonePodEvictor - workers that evicts pods from unresponsive nodes.
  • zoneNotReadyOrUnreachableTainer - workers that are responsible for tainting nodes.
  • podEvictionTimeout - 通过--pod-eviction-timeout设置,默认为5min,表示在强制删除Pod时,允许的最大的Pod eviction时间。
  • maximumGracePeriod - The maximum duration before a pod evicted from a node can be forcefully terminated. 不可配置,代码中写死为5min。
  • nodeLister - 用来获取Node数据的Interface。
  • daemonSetStore - 用来获取 daemonSet数据的Interface。在通过Eviction方式删除Pods时,会跳过该Node上所有的daemonSet对应的Pods。
  • taintManager - 它是一个NoExecuteTaintManager对象,当runTaintManager(默认true)为true时:
    • PodInformer和NodeInformer将监听到PodAdd,PodDelete,PodUpdate和NodeAdd,NodeDelete,NodeUpdate事件后,
    • 触发TraintManager执行对应的NoExecuteTaintManager.PodUpdatedNoExecuteTaintManager.NodeUpdated方法,
    • 将事件加入到对应的queue(podUpdateQueue and nodeUpdateQueue),TaintController会从这些queue中消费这些消息,
    • TaintController分别调用handlePodUpdate和handleNodeUpdate处理。
    • 具体的TaintController的处理逻辑,后续再单独分析。
  • forcefullyDeletePod - 该方法用来NodeController调用apiserver接口强制删除该Pod。用来删除那些被调度到kubelet version 小于v1.1.0 Node上的Pod,因为kubelet v1.1.0之前的版本不支持graceful termination。
  • computeZoneStateFunc - 该方法返回Zone中NotReadyNodes数量以及该Zone的state。
    • 如果没有一个Ready Node,则该node state为FullDisruption
    • 如果unhealthy Nodes所占的比例大于等于unhealthyZoneThreshold,则该node state为PartialDisruption;
    • 否则该node state就是Narmal
  • enterPartialDisruptionFunc - 该方法用当前node num对比largeClusterThreshold
    • 如果nodeNum > largeClusterThreshold则返回secondaryEvictionLimiterQPS(默认为0.01);
    • 否则返回0,表示停止evict操作。
  • enterFullDisruptionFunc - 用来获取evictionLimiterQPS(默认为0.1)的方法,关于evictionLimiterQPS的理解见下。
  • zoneStates - 表示各个zone的状态,状态值可以为
    • Initial;
    • Normal;
    • FullDisruption;
    • PartialDisruption;
  • evictionLimiterQPS - 通过--node-eviction-rate设置,默认为0.1,表示当某个Zone status为healthy时,每秒应该剔除的Nodes数量,即每10s剔除1个Node。
  • secondaryEvictionLimiterQPS - 通过--secondary-node-eviction-rate设置,默认为0.01,表示当某个Zone status为unhealthy时,每秒应该剔除的Nodes数量,即每100s剔除1个Node。
  • largeClusterThreshold - 通过--large-cluster-size-threshold设置,默认为50,表示当健康nodes组成的集群规模小于等于50时,secondary-node-eviction-rate将被设置为0。
  • unhealthyZoneThreshold - 通过--unhealthy-zone-threshold设置,默认为0.55,表示当某个Zone中unhealthy Nodes(最少为3)所占的比例达到0.55时,就认为该Zone的状态为unhealthy。
  • runTaintManager - 在--enable-taint-manager中指定,默认为true。如果为true,则表示NodeController将会启动TaintManager,由TaintManager负责将不能容忍该Taint的Nodes上的Pods进行evict操作。
  • useTaintBasedEvictions - 在--feature-gates中指定,默认TaintBasedEvictions=false,仍属于Alpha特性。如果为true,则表示将通过Taint Nodes的方式来Evict Pods。

关于Node Controller的其他博文:

  • Kubernetes Node Controller源码分析之执行篇
  • Kubernetes Node Controller源码分析之创建篇
  • Kubernetes Node Controller源码分析之配置篇

转载于:https://my.oschina.net/jxcdwangtao/blog/1454434

Kubernetes Node Controller源码分析之配置篇相关推荐

  1. 精尽 Dubbo 源码分析 —— API 配置

    1. 概述 Dubbo 的配置目前提供了四种配置方式:1. API 配置 2. 属性配置 3. XML 配置 4. 注解配置 2. 配置一览 我们来看看 dubbo-config-api 的项目结构, ...

  2. android agps,Android应用开发Android GPS ——AGPS源码分析及配置

    本文将带你了解Android应用开发Android GPS --AGPS源码分析及配置,希望本文对大家学Android有所帮助. " Android Framework GPS --AGPS ...

  3. android gps源码分析,Android编程之Android GPS ——AGPS源码分析及配置

    本文主要介绍了Android编程的Android GPS --AGPS源码分析及配置,通过具体的分析以及源码,向大家展示了这些,希望对大家学习Android编程有所帮助. 1:冷启动指令: locat ...

  4. hadoop作业初始化过程详解(源码分析第三篇)

    (一)概述 我们在上一篇blog已经详细的分析了一个作业从用户输入提交命令到到达JobTracker之前的各个过程.在作业到达JobTracker之后初始化之前,JobTracker会通过submit ...

  5. JUC源码分析-线程池篇(五):ForkJoinPool - 2

    通过上一篇(JUC源码分析-线程池篇(四):ForkJoinPool - 1)的讲解,相信同学们对 ForkJoinPool 已经有了一个大概的认识,本篇我们将通过分析源码的方式来深入了解 ForkJ ...

  6. photoshop-v.1.0.1源码分析第三篇–FilterInterface.p

    photoshop-v.1.0.1源码分析第三篇–FilterInterface.p 总体预览 一.源码预览 二.语法解释 三.结构预览 四:语句分析 五:思维导图 六:疑留问题 一.源码预览 {Ph ...

  7. k8s replicaset controller源码分析(1)- 初始化与启动分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  8. Kubernetes Client-go Informer 源码分析

    几乎所有的Controller manager 和CRD Controller 都会使用Client-go 的Informer 函数,这样通过Watch 或者Get List 可以获取对应的Objec ...

  9. k8s replicaset controller源码分析(2)-核心处理逻辑分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

最新文章

  1. Mac python3.x使用HTMLTestRunner.py
  2. 在windows上模拟linux环境,MSYS2——Windows平台下模拟linux环境的搭建-Go语言中文社区...
  3. 华为2013校园招聘上机笔试题
  4. P2668 斗地主 dp+深搜版
  5. php ajax 分页phpapi,ajax分页_php ajax分页代码
  6. BCVP开发者说第3期:Adnc
  7. 参加开发竞赛遇到的问题【总结】
  8. 解决Yii2邮件发送问题(结果返回成功,但接收不到邮件)
  9. C++算法二:冒泡排序
  10. Java 基础 —— enum
  11. java并发编程(2)--线程 原子性 volatile AtomicInteger
  12. c语言乘法怎么手写,发现要实现手写乘法计算过程也让我头疼
  13. HTML5技术的调研以及贴吧应用总结
  14. win8卸载java环境_Win8.1系统如何解压/卸载install.wim文件
  15. 1.488Mpps是如何计算出来的?
  16. 【ReentrantLock】
  17. 《软件工程与计算(卷二)》-Chapter22-23-软件开发过程模型与软件工程职业基础
  18. npm install下载包的时候报4048rename的错误
  19. HC32L110(五) Ubuntu20.04 VSCode的Debug环境配置
  20. 李想的理想 IPO :新造车「异类」背后的思考

热门文章

  1. linux更改文件属性宁静,shell /dev/null 21 ( linux空设备文件和重定向)
  2. java web简单线上游戏_有什么在线的编程游戏?
  3. 寻找亚马逊测评师邮箱_你真的会精细化运营吗?毫无保留地分享亚马逊运营小技巧,月入过万不是事...
  4. markdown 图片居中_写作者必备技能:markdown 微信使用markdown
  5. Vue多组件切换,并相互传值(在created和mounted生命周期钩子函数中渲染数据的区别)
  6. 2021年南菁高中高考成绩查询,2021年无锡高考各高中成绩及本科升学率数据排名及分析...
  7. 数字ab写成c语言表达式,《c语言程序设计》复习题.pdf
  8. springboot整合freemarker中文乱码
  9. 史上最全的键盘快捷键
  10. 腾讯已问灵魂,鹅厂新立家风