文档章节

Kubernetes Node Controller源码分析之配置篇

WaltonWang
 WaltonWang
发布于 2017/07/18 00:48
字数 1625
阅读 377
收藏 3
点赞 0
评论 0

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方法启动该Controller
	nodeController.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 bool
	cloud             cloudprovider.Interface
	clusterCIDR       *net.IPNet
	serviceCIDR       *net.IPNet
	knownNodeSet      map[string]*v1.Node
	kubeClient        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]nodeStatusData
	now           func() metav1.Time
	// Lock to access evictor workers
	evictorLock sync.Mutex
	// workers that evicts pods from unresponsive nodes.
	zonePodEvictor map[string]*RateLimitedTimedQueue
	// workers that are responsible for tainting nodes.
	zoneNotReadyOrUnreachableTainer map[string]*RateLimitedTimedQueue
	podEvictionTimeout              time.Duration
	// The maximum duration before a pod evicted from a node can be forcefully terminated.
	maximumGracePeriod time.Duration
	recorder           record.EventRecorder

	nodeLister         corelisters.NodeLister
	nodeInformerSynced cache.InformerSynced

	daemonSetStore          extensionslisters.DaemonSetLister
	daemonSetInformerSynced cache.InformerSynced

	podInformerSynced cache.InformerSynced

	// allocate/recycle CIDRs for node if allocateNodeCIDRs == true
	cidrAllocator CIDRAllocator
	// manages taints
	taintManager *NoExecuteTaintManager

	forcefullyDeletePod        func(*v1.Pod) error
	nodeExistsInCloudProvider  func(types.NodeName) (bool, error)
	computeZoneStateFunc       func(nodeConditions []*v1.NodeCondition) (int, zoneState)
	enterPartialDisruptionFunc func(nodeNum int) float32
	enterFullDisruptionFunc    func(nodeNum int) float32

	zoneStates                  map[string]zoneState
	evictionLimiterQPS          float32
	secondaryEvictionLimiterQPS float32
	largeClusterThreshold       int32
	unhealthyZoneThreshold      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的其他博文:

© 著作权归作者所有

共有 人打赏支持
WaltonWang
粉丝 158
博文 88
码字总数 182269
作品 0
深圳
程序员
浙江大学软件工程实验室关于Docker和KUBERNETES的分析文章

DOCKER源码分析(一):DOCKER架构, 2014.12.02, http://www.sel.zju.edu.cn/?p=112 DOCKER源码分析(二):DOCKER CLIENT创建与命令执行, 2014.12.02, http://www.sel.zju.edu.cn/?p=147 DO......

一配 ⋅ 2015/08/30 ⋅ 1

Kubernetes1.10 ——二进制集群部署

之前的博文中已经介绍过使用kubeadm自动化安装Kubernetes ,但是由于各个组件都是以容器的方式运行,对于具体的配置细节没有太多涉及,为了更好的理解Kubernetes中各个组件的作用,本篇博文将...

酥心糖 ⋅ 05/25 ⋅ 0

Kubernetes 1.2版本之简单安装

本篇文章,仅是用于尝鲜 Kubernetes 1.2版本的dashboard,具体其他使用,有机会在做介绍,稍后会写篇关于kubernetes-dashboard安装配置的文档 说明下,Kubernetes 1.2版本的kubelet启动,需要...

perofu ⋅ 2016/05/19 ⋅ 0

Centos7 安装 Kubernetes 集群详细步骤(安装篇)

Kubernetes 是goole开源的大规模容器集群管理系统,使用centos7 自带的Kubernetes 组件、分布式键值存储系统etcd 以及flannel 实现Docker容器中跨容器访问。 (集群环境需要ntp时钟一致,因为...

crazy_charles ⋅ 2017/07/07 ⋅ 0

kubernetes DaemonSet资源对象

What is a DaemonSet? DaemonSet能够让所有(或者一些特定)的Node节点运行同一个pod。当节点加入到kubernetes集群中,pod会被(DaemonSet)调度到该节点上运行,当节点从kubernetes集群中被...

yzy121403725 ⋅ 04/13 ⋅ 0

kubernetes集群部署

鉴于docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试。kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,coreos,aws等iaas平台,部署起来...

Hi徐敏 ⋅ 2015/10/13 ⋅ 0

Kubernetes集群部署1

1.规划 192.168.100.102------>Master[kube-apiserver、kube-controller-manager、kube-scheduler] Node[kubelet、kube-proxy] 192.168.100.103------>Node1[kubelet、kube-proxy] 192.168.1......

结束的伤感 ⋅ 2017/11/27 ⋅ 0

多节点部署Kubernetes dashboard UI详细流程

Kubernetes要做的一个最重要的工作就是实现Docker容器的集群,并且一般都是在不同的物理机器上。我们通过使用命令行来操作Kubernetes,但是如果有一个UI界面来可视化操作,岂不是更方便。本篇...

CHENYUFENG1991 ⋅ 02/04 ⋅ 0

全视角了解基于容器的编排工具Kubernetes

Kubernetes在希腊语中是“船长”或者“水手”的意思,Kubernetes诞生于谷歌,2014年开源给了CNCF。它由Go语言开发,目标是建造一个运行大量容器生产环境的强大平台。Kubernetes库可以在GitHu...

m2l0zgssvc7r69efdtj ⋅ 05/24 ⋅ 0

Kubernetes内部组件工作原理介绍

本篇文章讲述了Kubernetes内部组件的工作原理,及创建Pod的流程。如果你是运维人员或者是Kubernetes的使用者,你可以不需要知道Kubernetes的内部工作原理,但是如果你想理解Kubernetes内部的...

Docker ⋅ 04/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

骰子游戏代码开源地址

因为阿里云现在服务器已经停用了,所以上面的配置已经失效。 服务端开源地址:https://gitee.com/goalya/chat4.git 客户端开源地址:https://gitee.com/goalya/client4.git 具体运行界面请参考...

算法之名 ⋅ 41分钟前 ⋅ 0

设计模式--装饰者模式

装饰者模式 定义 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。 通用类图 意图 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比...

gaob2001 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部