锅炉信息网 > 锅炉知识 > 锅炉资讯

K8s调度器Scheduler

发布时间:

当创建k8s pod的时候调度器会决定pod在哪个node上被创建且运行,调度器给apiserver发出了一个创建pod的api请求,apiserver首先将pod


当创建k8s pod的时候调度器会决定pod在哪个node上被创建且运行,



调度器给apiserver发出了一个创建pod的api请求,apiserver首先将pod的基本信息保存在etcd,apiserver又会把这些信息给到每个node上的kubelet进程,kubelet一直在监听这些信息,当kubelet发现这个pod的节点信息跟它当前运行的节点一致的时候,就会创建pod进程以及容器当中的docker image进程,创建相应的命名空间,使得进程之间互相隔离,这样pod就在这个节点上运行起来了。

k8s调度器会尽量的去保证所有节点上的资源是相对平衡的,判断节点资源(CPU、内存、存储、端口等)是否适合Pod的资源申请。

查看K8s资源在etcd中的信息

借助kube-etcd-helper这个工具查看etcd中的内容,



写一个操作etcd命令的脚本./etcdheloper.sh,指定etcd的地址,鉴权需要的证书等信息,



查看k8s资源列表,./etcdheloper.sh ls



这是etcd中保存的k8s资源信息,查看指定的pod信息,


跟调度器相关的是这个nodeName,




验证调度器的工作方式

有了etcd helper可以更加详细的看下调度器的工作原理,调度器一直在监听k8s中的pod的创建,通过etcd watch的功能可以去监听一个pod的创建并且看到创建的整个过程。



创建这个pod,使用etcd helper来监听下这个pod在etcd当中变动的过程,


通过这个命令可以看到在etcd中关于这个pod产生了4次变动,每次变动都是一个json,通过JSON Diff工具比较每次json都变动了哪些内容,

第一个json和第二个json比较,多了一个nodeName,


第一次给apiserver发送请求把这个信息保存在etcd当中的时候还没有nodeName,第二次就是更新nodeName,调度器通过算法决定了这个pod要在这个node上创建,



这里声明了pod已经被调度了;

第三次的json相比第二次json的变更内容:


记录了pod中container容器的启动状态和pod的ip。

Pod指定节点运行



这是集群中node的情况,

查看指定node的详情,红色部分决定了node的名称,



这个分别代表节点所在的区域和时区,



每个地域完全独立,但同一个地域的可用区中间是互通的。

地域是指电力和网络互相独立的区域;同一可用区内实例之间的网络延迟更小;

关键点是电力和网络相互独立,这个是在灾备的时候要考虑的。

数据库、k8s的节点、消息队列等常用的资源都是需要做冗余的,如果在一个可用区内做大量的冗余,

看起来比较安全,一旦这个可用区废掉了,所有的冗余信息在短时间内是不可工作的,跨可用区做冗余可用性就会得到极大的增强。





pod在指定的node上运行。

正常工作的节点



这是正常工作的节点,pod通过kubelet这个进程被创建出来。

kubectl向apiserver发送了一个请求,apiserver就把请求信息存储在etcd数据库里,调度器通过事件的监听,通过调度算法来决定pod将会被调度到哪个节点上去,确定是哪个node之后,所以就在etcd的pod信息里面增加了一个nodeName。

kubelet也进行监听,当它发现调度器分配这个pod到某一个节点信息修改的时候,来看这个节点是不是属于它当前运行的node,如果是的话,就会创建这个pod。

k8s是go语言写的,一般用glog打日志,



k8s 基于glog fork出来一个klog,k8s内核是用klog来记录日志的。



glog有个参数:-v,表示日志的详细程度,



从日志中可以看到,在创建pod的时候,先判断pod是否存在,如果不存在的话,则创建。

有2种情况不属于正常工作的节点,



pod不能被调度到节点或者pod根本不可以在节点上运行,比如这个节点的systemd后台进程有问题导致节点不能正常运行,并不代表节点所在的虚拟机崩溃了,但是作为k8s节点是不能正常运行的,这种情况下node被打上一个污点。

NoScheduler表示不能调度到指定节点上;

NoExecute表示新的pod将不可以被调度到指定node上运行,当前在上面运行的pod也将被驱逐。





参数名称可以任意起,污点一旦被创建,对节点就生效了,ubuntu这个pod状态一直pending,就表示调度不过去 ,原因就是因为这个node被打上了污点。



解除污点,pod就被调度到这个node节点上启动了。



给node打上NoExecute污点,



这个节点上面的这个pod直接就停掉了,



去掉NoExecute污点,新的pod就可以在这个节点上运行了。

给node打污点的情况实际用的比较少,除非排错,比如pod还能在node上跑,不希望新的pod被调度过来,先打一个污点,再在上面排查问题。

如果要重启node或修改配置,一般通过拉警戒线的方式,



跟打污点的效果是一样的,


去除警戒线。

打污点或拉警戒线的使用场景:

场景1,比如阿里云systemd进程因版本的问题需要升级,会用这个命令,

场景2,节点有特殊的工作用途,比如master节点,一般至少用2个node做master节点,阿里云可以去托管master节点,比如当前的集群中只有worker节点没有master节点是因为被阿里云托管了,对于这种情况也需要给master node打上污点,不将pod调度到master node上去。

打污点key有两种形式,一种是以字符串label的方式,





另外一种比如env=prod,


表示节点是测试环境还是生产环境。

除非pod有env=prod并且可以容忍NoExecute这样的标签,才能被调度在这个pod上,


node亲和性



node1 16核64G内存,node2 16核64G内存,node3 32核 64G内存,让pod向性能比较好的node上运行即pod亲和node3,


pod亲和于什么样的node去运行,在调度的时候affinity是必须的,但在实际运行的时候又用不到,只是调度的时候用到。



在调度的时候80%的概率到一个node,20%的概率到另外一个node。

pod的亲和性



details pod运行在哪个node上,ubuntu pod也运行在details pod所在的node上,



实际运用的场景比如前后端的pod运行在同一个node上。启动pod的时候去查有没有满足app:details这个条件的pod,如果有的话,就在运行在这个pod所在的node上。

pod的反亲和性

每个node有不同的hostname,如果发现这个node上已经运行了跟我一样label的pod,那我就不在这个node上运行了,再找一个新的node即同样的一个pod不在同一个node上运行这样的效果,



65这个node上已经运行了ubuntu了,


再启动一个ubuntu,就不会在65这个node上运行了,而是在124这个node上运行,



再运行ubuntu3和ubuntu4,为什么ubuntu4一直pending是因为每个node上都有ubuntu了,4没有node可以运行了。

pod亲和度使用场景比较多,node亲和度几乎用不到,因为同一个集群,尽量使用同样的ecs虚拟机,尽量不要有差异化。



就算要区分环境,比如这2台配置比较小的机器做测试环境,(生产环境的机器要比测试环境多的多,这里只是做假设),更倾向于配成2个不同的vpc(私有云)


,每个vpc有自己独立的网段,2个vpc相对安全些,让2个网段互通可以使用阿里云的cen,


这样比较好,而不是做一个大的集群(里面什么样的node都有),再通过打污点、打标签,个人感觉这样会比较累。

精选推荐

  • 如何正确选择白板供应商
    如何正确选择白板供应商

    目前在无锡想采购一块白板不管是实体店铺,还是网络平台都有很多选择,想要到专业的无锡白板公司采购还需要掌握一定的方式技巧。现

  • 柴油发电机组供应商
    柴油发电机组供应商

      t 扬州华东动力机械有限公司,位于江苏省扬州市江都区仙城工业园,是专业从事发电机、柴油及燃气发电机组研发、制造、销售、服务于

  • 高温辐射炉
    高温辐射炉

    5.2.2高温辐射炉5.2.2.1温度控制★(1)样品温度范围:常温~1400℃。★(2)均温区:长度不小于80mm。★(3)中心区:长度不小于10mm。(4)温度梯度(均

  • 高压锅在什么情况下会爆炸?
    高压锅在什么情况下会爆炸?

    近日,多地发生高压锅爆炸事故,给不少家庭带来了伤害和财产损失。那么,什么情况下会导致高压锅爆炸呢?首先,当高压锅内部压力过高时,如果

0