白话K8S核心组件概念
背景前不久公司领导跟我聊天,K8S是什么? 它能干什么?二话不说,直接搬出概念,它的本质是工业级编排平台,负责容器的弹性、管理和编排。我之前没有怎么接触K8S相关的概念,啥是容器?怎么弹...
背景
前不久公司领导跟我聊天,
K8S是什么? 它能干什么?
二话不说,直接搬出概念,它的本质是工业级编排平台,负责容器的弹性、管理和编排。
我之前没有怎么接触
K8S相关的概念,啥是容器?怎么弹性?如何管理和编排?
容器是利用了集装箱的思想,把可运行程序打包成可运行、自包含、标准化的镜像。通过K8S能够管理和编排我们打的镜像,举例来说,如果你想运行两个副本,直接在编排文件中配置replicas为2即可,你也可以使用HPA通过检测CPU、内存使用率实现自动扩缩容。
又是镜像,又是编排,引入这么多新概念,能
hold住?你就给我说说,它和SpringCloud、dubbo...等微服务框架有什么不同?
SpringCloud、dubbo等框架和K8S切入点不同,K8S能够支撑所有框架和语言,并提供了平台级别的服务;而SpringCloud仅仅是整合了Java库以及各种运行时概念,是通过JVM级别来管理的。
到此结束吧,说到底,还是没有讲清楚它的本质、不能用通俗易懂的语言说清楚
K8S到底是什么!
对于一个没有接触到云原生概念的人,如何讲清楚云原生时代的操作系统K8S到底是什么?和普通微服务框架有什么区别?如果问我K8S中的核心组件的功能,又该如何解答?
后来仔细想了想, 可以把K8S比喻成一栋精装修大楼,每间都是统一的标准,拎包入住即可;而其它的一些微服务框架则可以看作毛坯房,需要各种定制化,无法做到开箱即用,至于精装修是否适合自己,还要看自己房子的数量。
就本人而言是不喜欢拿IT技术打比方的,因为IT技术是一门严谨的科学,通过打比方的方式,虽然能够对一门技术有个大致的了解,但是不能从根本上搞明白核心技术点,从而不能起到关键性帮助,有时还会造成曲解。所以直接抠概念中核心关键点文档即可。
本文会用本人自己通俗的语言叙述K8S中核心组件的概念,概念段落中黑体字会用浅显易懂的语言描述该概念,紧接着会进一步解释该组件的功能。适用于K8S小白,如果你是高手,出门左转,不送!
Controller-控制器
-
宏观上来说
控制器本质上就是一个死循环,不断获取实际状态,然后跟期望状态做对比,通过对比决定下一步的操作;如果跟实际状态一致,维持现状,否则将实际状态调整为期望状态。
-
微观上来说
控制器的设计原理是用一种对象控制另一种对象的艺术。
另外我们在一些架构图中经常看到kube controller manager和cloud ontroller manager,其中kube controller manager就是我们常见的有Pod控制器、Deployment控制器....的实现。cloud ontroller manager是对route控制器、Service控制器,之所以会出现cloud mananger controller是因为在不通的云环境中、控制器的实现会因为云厂商、环境的不同,存在一定的差别。
总结来说,控制器就是整个集群的大脑,有了控制器才能使集群更加智能。
Scheduler-调度器
从大体上来说,是一个择优而居的过程,调度器就是为Pod选择一个合适Node,让Pod的定义的任务在这个node上顺利完成。

整个过程如下图:
Informer Path
第一个控制循环我们称之为Informer Path,它启动一系列的Informer,用来监听etcd中Pod、Node、Service等资源对象的变化,并通过Informer Handler把待调度Pod加入的到优先级队列,Node等信息缓存到Cache中。
-
Informer是Client-go中的一个核心工具包。内部实现极其复杂,简单来说是一个依赖K8s List/watch API,可以监听事件并触发回调函数的工具包。 -
Priority Queue K8s的调度队列,之所以在这里添加调度队列主要是出于对调度优先级和抢占的考虑,通过使用调度队列可以对调度中的内容做特殊操作。 -
Scheduler cache调度器缓存,最大程度上将集群信息缓存化,提高Predicte调度算法的执行效率。
Scheduling Path
第二个控制循环是调度器负责Pod调度的主循环,称之为Scheduling Path,主要逻辑就是不断的从队列里拿出Pod,然后调用Predictates进行过滤,这一步的过滤是得到一组满足条件的Node,当然这些Node都是从cache中直接拿到的,接下来再调用Priority算法为上述列表中的Node打分,分数从0-10,得分最高的Node将会被选中。调度算法完成后需要将Pod和NodeName进行绑定,这个过程就是最后一步Bind,当然这个Bind只是更新缓存中绑定信息,称之为乐观绑定。
-
Predicates在调度过程中的作用,可以理解为filter,它按照调度策略,从集群节点中过滤出一系列符合条件的节点。这些节点都是可以运行待调度Pod的宿主机。 -
Priorities阶段的工作主要就是为这些节点大根,这个打分的范围是0-10分,得分最高的节点就是Pod绑定的最佳节点。
APIServer
对比Kubernetes和单机操作系统,Kubernetes相当于操作系统,控制着整个集群硬件资源管理,并提供统一的入口,用户可以通过这个入口使用集群、这个入口正是API Server,通过这个入口,使我们才能进入K8S内部操作其资源对象。
举个例子,一个Pod从提交到运行时序图,如下所示:
-
提交一个
yaml编排文件到APIServer -
APIServer会把创建Pod编排文件信息透传到etcd数据库中 -
调度器
Scheduler通过listandwatch观察到有新的Pod需要调度,调度器会为这个Pod寻找一个合适的节点并放置上去,并且把节点信息回传到APIServer保存到etcd中 -
Kubelet发现有一个Pod调度到自己所在节点,会进行docker run操作启动服务,并且把Pod状态信息回传给APIServer,最终APIServer把Pod信息记录到etcd中。
通过这幅图可以看出一个Pod在创建过程,除了APIServer之外,其它组件之间的通信都要经过APIServer。但是你可能会产生一个疑问,控制器呢?请看下图,控制器正是保证和控制服务正常运行的大脑。
etcd
etcd是一个分布式,可靠的key value存储系统,它用于存储分布式系统中的关键数据。得益于etcd自身的租约、历史数据版本控制等机制,Kubernetes自身状态数据流转到etcd中,Kubernetes自身不在需要处理复杂的状态数据,从而简化Kubernetes自身架构。
一个
etcd集群,通常会由3个或者5个节点组成,多个节点之间,通过一个叫做Raft一致性算法的方式完成分布式一致性协同,算法会选举出一个主节点作为leader,由leader负责数据的同步与数据的分发,当leader出现故障后,系统会自动地选取另一个节点成为leader,并重新完成数据的同步与分发。客户端在众多的leader中,仅需要选择其中的一个就可以完成数据的读写。其内部机制非常复杂,采用B+树数据存储,但是对外提供接口非常简单,我们可以直接通过HTTP协议进行访问。
ETCD中主要使用使用场景有选主、并发控制进程执行、服务发现(租约检测节点存活}、版本机制控制历史数据
总结
本文主要是通过通俗易懂的语言描述了K8S中核心组件的功能以及用途,使其看起来简单,但内部执行流程及细节却是非常复杂,本人目前也正在阅读和实践client-go的源码,后续会有输出,欢迎有兴趣的同学,关注公众号、加我微信一起讨论。
推荐
从Ice到Kubernetes容器技术,微服务架构经历了什么?
原创不易,随手关注或者”三连“,诚挚感谢!
更多推荐



所有评论(0)