k8s 自身原理 2

前面我们说到 K8S 的基本原理和涉及的四大组件,分享了前两个组件 etcd 和 ApiServer

这一次我们接着分享一波:

  • 调度器 scheduler
  • 控制器管理器 controller manager

调度器 scheduler

调度器,见名知意,用于调度 k8s 资源的,那么这个调度器具体主要是调度啥资源呢?

实际上看我们 k8s 中运行的一个一个的 pod,这些 pod 在我们创建的时候,还记得我们有分享过是可以指定即将要生成的 pod 默认被调度了指定节点吗?

一般情况下,我们也没有去刻意指定 pod 要调度到哪个节点,但是最终 pod 一定会被调度到集群中的某一个节点

实际上,这就是调度器在起作用了,没错,调度器就是调度 pod 资源到对应的节点上

咱们的调度器也是利用了 API 服务器的监听机制来新创建 pod 资源的,创建好的 pod 资源,会将其调度到资源充足,甚至没有 pod 的节点上

那么你是否会认为是调度器直接控制节点来运行指定的 pod?

nonono,并不是这样的,前面我们有说到过基本上很多的组件都是通过 ApiServer 来进行处理的

调度器在这里也不例外,

这里的是调度器是通过 ApiServer 来更新 pod 的定义,然后 ApiServer 再去通知 Kubelet 这个 pod 已经被调度器调度过了,这个时候,实际对应节点上的 Kubelet 发现自己节点上有 pod 被调度过来,那么 kubelet 就会创建并且运行 pod 中的容器

那么 k8s 默认是如何调度 pod 的?总有一个优先级吧

是的没错,总会有一定的规则,咱们画个图来感受一下:

例如一开始集群中有 4 个节点,在运行过程中,节点 2 和 节点 3 变为不可用了,接下来,若有新的 pod 需要调度,那么调度器会从可用的 2 个节点里面选择一个最优的节点,

例如磁盘,内存空间较大,或者 pod 资源个数较少的,会按照综合优先级递减排序,

例如就会生成 pod 调度到节点 4

那么问题就来了,k8s 是如何找到满足需求的可用节点呢?

当然 k8s 找到可用节点的条件也是不少了,不是随便一个节点就可以接得住的,例如 k8s 会检查这些条件

  • 节点的资源是否被耗尽了
  • pod 是否设置了一定要 / 一定不要 调度到某一个节点上
  • 如果这个 pod 需要绑定主机的端口,那么该节点的端口是否被占用了
  • 节点可以满足创建 pod 对应硬件资源的要求吗
  • 该节点上有没有和我们即将要创建的 pod 参数和规格一致的标签呢
  • pod 若需要特定的卷,该节点支持吗
  • … 等等

以上的条件都必须要满足,才有机会将 pod 调度到这个节点上来

我们是否可以设置 pod 全部集中在一个节点,或者分散到多个节点中去呢?

实际上我们知道管理 pod 的资源是 RS / RC,一般情况下 他们会尽可能的将 pod 分散到不同的节点上面,但是也不能保证每一次都是这样的

如果我们自己有需求,可以在 pod 模板中设置 pod 的亲缘性 和 非亲缘性来设置定,pod 调度到哪些符合要求的节点上去

总的来说,pod 分散到不同的节点可以降低风险,增强健壮性,若其中一个节点挂掉,并不会应 pod 提供的服务

之前说到 etcd ,ApiServer 都可以是多个的,那么这里的调度器仍然可以是多个,若是真的只有一个调度器,服务多了之后他也扛不住嘞

我们也可以看到 kube-system 命名空间中

这些核心组件都是以 pod 的方式运行的,如果我们需要多个 scheduler,那么就多创建几个就好了

但是我们在创建 pod 的时候,如果没有指定使用哪一个调度器去调度的话,那么 k8s 中会使用默认的调度器,如果我们有需求,实际可以在 pod 模板中使用 shedulerName 关键字来指定调度器的名字

控制器管理器 controller manager

控制器管理器 controller manager 见名知意,他是一个管理器 manager,管理的对象是控制器 controller

Replication 管理器,我们可以理解为资源管理器,也就是我们之前学过的 RC ,ReplicationController

控制器的话就比较多了,之前我们学过的大部分资源,都有对应的控制器进行管控,例如:

  • Node 控制器
  • Service 控制器
  • Endpoints 控制器
  • Namespace 控制器
  • ReplicaSet 控制器
  • DaemonSet 控制器
  • Job 控制器
  • Deployment 控制器
  • StatefulSet 控制器
  • PersistentVolume 控制器

为啥需要控制器管理器?

之前分享的各个组件中,他们就好像只管好自己就可以独善其身了,总得有一个角色为大家负重前行吧

比如说, ApiServer 只去和 etcd 交互,然后通知监听的客户端有变更 , 调度器 Scheduler 又仅仅是给 pod 分配节点

那么对于资源的扩缩容,以及资源的期望状态,又谁来进行监听和处理呢?

那就得 控制器管理器了

那么我们上述的控制器主要是干啥?

首先通过控制器的名字,我们应该是知道这些控制器主要是控制自己对应资源的状态的

然而不仅仅是这一点哦,控制器做的事情就稍微杂一点,综合能力比较强

例如:

  • 控制器会监听 ApiServer 资源变更
  • 执行相应的操作,例如创建,编辑,删除,查看等等

这里的控制器也是不会相互通信的,都是和 ApiServer 交互,可以理解为 控制器一直在做满足别人期望的事情,是一个调和的角色

例如,我们将期望的副本数,改变了,那么控制器便会去处理,直到满足期望后,将最新的状态写入资源的 status

那么 Replication 管理器又是何方神圣?

刚才有说到他是管理控制器的,控制器又那么多,可以把他看做控制器的管家吧

官方定义,启动 ReplicationController 资源的控制器叫做 Replication 管理器

那么对于 RC 的行为我们应该心里都有数吧,当修改了 RC 的副本数之后,RC 回去调和 pod 的数量

这个实际动作,其实是 Replication 管理器 这个幕后大佬做的

之前我们说到 RC 的时候,当我们修改这个副本数,大家是否会认为, k8s 中会有一个轮询机制,当获取到 RC 的副本变化的时候,会去满足期望?

实际上也是和 ApiServer 那一块分享的类似,此处也是用到了监听机制,控制器会通过监听机制订阅可能会影响期望副本数的变更事件

若有变更事情时,则会做出相应动作

RC 会实际去运行 pod 吗?

看到这里,是否还会有疑问,既然 RC 会去满足期望,那么是 RC 直接去运行的 pod 吗?

并不是的

当出现当前数量和期望副本数量不一致的时候, RC 回去创建新的 pod 清单,并发布到 APiServer 上,最终会让调度器和节点上的 Kubelet 来调度 pod 并运行 pod

管理器管理那么多的控制器,肯定有一个统一管理资源的管理流程的,具体的简单流程如下:

image-20220219122523501

简单来说,就是 Replication 管理器会监听具体的资源,然后通过 ApiServer 来操作对应的资源对象,最终达到更新的目的

当然,其他控制器也是这样的,都是监听资源,通过 ApiServer 进行更新资源

每一种控制器,实际上我们在分享到其对应资源的时候,基本都有分享到他们的行为,这里就不再重复了

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

posted @ 2023-08-10 22:54  阿兵云原生  阅读(26)  评论(0编辑  收藏  举报