K8凯发·国际

02K8S架构详解

日期:2025-05-31

  API-Server充当了整个K8S集群的入口点★★,负责接受整个集群的所有内部请求■★◆◆◆.这里的请求并不是外界访问我们部署的应用的请求,而是k8s内部通过请求以达到预期的最终状态★★,通常涉及更改集群的状态或者管理集群的资源。

  kubelet是每个节点的代理,它会把Node注册到K8S集群中,会在集群中的每一个node上运行★★,它保证容器按照期望情况运行在Pod中。它接受一组PodSpecs,这一组PodSpecs用来描述pod的期望运行状态,kubelet不会管理不是由K8S创建的容器。

  此外,如果想要做到更细粒度的资源监控,比如Deployment★★◆★★、Pod、容器级别,那么单单靠Kubelet是不行的,可以通过访问API-Server◆★★★◆★,或者使用其他工具进行数据上报,比如Prometheus、Grafana等等★◆★■★。

  节点控制器负载在云基础设施中创建了新服务器时,为之更新节点对象◆★◆,节点控制器从云提供商获取当前租户中主机的信息,节点控制器执行以下功能:

  也就是说kubelet的作用主要有两个■◆,即确保容器在节点上正确运行和与Master节点进行通信◆★◆◆■,下面我们从几个方向详解kubelet的具体作用。

  在成功创建这个Pod之后■◆,Kubelet会定期监控container-1容器的健康状态,以确保它能够正常运行;并且会定期向Master报告节点的资源使用情况,如果容器崩溃或者终止,kubelet会尝试重启它■■◆,以确保Pod中的容器处于预期状态。

  它会维护节点上的一些网络规则★■,这些规则会允许从集群内部或者外部的网络与Pod进行通信,以便将流量路由到正确的Pod◆◆◆◆★。

  4.检查节点的健康状态★★■■★★,如果节点无响应,控制器通过云平台API查看该节点是否已从云中、删除或终止。如果节点已经从云中删除,则控制器也会将节点从K8S内部集群中删除◆■★★■。

  container-Runtime组件使得K8S拥有容器运行的环境和条件,从而能够有效运行容器。它负责管理K8S环境中容器的执行和生命周期■★◆。

  cloud-controller-manager与kube-controller-manager类似,也是一个控制器管理器,这个组件主要是和云厂商相关的,如果你是自己搭建的集群,那么就不会有这个组件。

  在下一篇中我会带着大家搭建K8S环境■★■★,线S的具体操作,感兴趣的小伙伴欢迎点赞、评论◆■、收藏,您的支持就是对我最大的鼓励。

  K8S早期版本仅仅适用于Docker Engine这一种特定的容器运行时★◆◆★◆◆,后来增加了对其他类型的容器运行时的接口,因此设置了CRI标准接口来和各种各样的容器运行时进行交互,它包括了容器运行时的接口和镜像的接口,我们可以看看这些接口的定义。

  这是因为在修改文件的时候,我们的对象已经被其他因素修改了★■,并且数据同步到etcd中★■◆★■,使得该对象的版本号+1,我们再次保存修改的时候,版本号落后于ectd中对象的版本号,于是会修改失败◆■■。

  kube-proxy是集群每个Node上运行的网络代理◆◆■★■,以确保Pod之间的通信◆■,以及Pod和集群外部的通信是正常的。

  这些不同的控制器会负责管理、调整其管理的对象,比如Deployment就负责管理所有的Deployment对象,每一个控制器是一个独立的进程,但是K8S为了降低管理这一系列控制器的复杂度,将它们编译成了同一个二进制文件,并且运行在同一进程里。

  同时◆■,在K8S中每个资源对象都有一个ResoureVersion字段,代表了该对象的版本号,因为K8S使用乐观并发控制来处理并发访问,这个版本号会在对象发生改变的时候递增★◆■■★■。所以当我们手动修改某个对象的时候,比如kubectl edit deployment my-deployment -n mynamepsace的时候,有可能保存文件之后提示因为resourceVersion更新对象失败的提示◆■◆■★★。

  《每天十分钟■◆★★,轻松入门K8S》的第二篇02◆■.K8S架构详解到这里就结束了,感谢您看到这里。

  它嵌入了特定于云平台的控制逻辑,cloud-controller-manager允许你将你的集群连接到云提供商的API之上,这是一个可插拔式的组件■★■◆,使得不同的云厂商都能够将其平台与K8S集成。

  上面的这些接口都是容器运行时需要暴露给Kubelet的接口,Docker Engine没有实现CRI接口◆■,所以当K8S创建了CRI标准之后,手动创建了部分特殊代码来帮助Docker Engine过度,也就是dockershim。

  其中,控制平面的组件也可以被部署成多个实例以提供冗余和负载均衡■★◆。另外,工作结点之间也是对等的★◆,可以随时向集群中添加或者删除节点◆■★。

  这样的话◆◆■◆★★,成为Leader的那个实例将负责执行所有控制器的工作,能够显著降低控制器选主部分的复杂性,保证整个Controller Manager和各个Controller集群的高可用性和一致性。

  当然,我们也可以编写自定义的调度器拓展,来实现我们想要的定制化pod调度策略◆■◆■◆■,例如pod不会调度到cpu负载超过50%的Node上。

  从可拓展性的角度看,K8S通过引入新的容器运行时接口将容器管理与具体的运行时解耦,不再依赖某个具体的运行时实现。另外,Docker也不打算支持K8S中的CRI接口,需要K8S社区在仓库中维护Dockershim。此外■◆■◆★★,在较新的CRI运行时中实现了与dockershim不兼容的功能★◆★★,例如cgroups v2和用户命名空间。 从Kubernetes中移除dockershim允许在这些领域进行进一步的开发★◆■★◆。

  2.利用特定云平台的信息为Node对象添加注解和标签,例如节点所在的区域,和所具有的资源等等。

  在K8S中,每个对象都由四部分组成,即Api-version、Kind、Metadata、Spec、Status,其中Spec直译过来是规约的意思,我们可以理解Spec是对象想要达到的状态,Status则是目前的状态,K8S会努力让Status不断变化,直至和Spec约定的状态达到一致。

  服务控制器与云平台的组件集成,如负载均衡器、IP地址、网络包过滤、目标健康检查等等。服务控制器会和云平台提供商的API进行交互,以进行上述组件的配置。

  如果操作系统提供了可用的数据包过滤层,则kube-proxy会通过它来实现网络规则■■。否则,kube-proxy只做流量转发的功能。

  kube-scheduler负责将新创建的pod调度到合适的node上,它会考虑多种因素★◆■,以确保最后部署的Node是最佳选择★■◆,比如以下因素★■◆★。

  etcd是一个分布式的Key-Value系统,它并不直接参与编排,而是负责维护集群的配置信息和状态,包括配置、各种对象的状态、服务定义等等。

  K8S采用了分布式、去中心化的架构,由分布式控制平面和多节点的工作节点组成★■◆■◆◆,K8S的核心设计目标之一是高可用性和高伸缩性,因此它并没有采用一主多从这种分布式架构模式◆■★■。

  这么做也是有原因的,当系统存在多个controller-manager的时候,K8S就需要选举出一个控制器的主节点作为集群的Leader,其他的节点被认为是从节点,当这些控制器被编译在一个二进制文件中的时候,只需要将这一个Controller Manager实例选举为Leader即可,而不需要每一种控制器都有自己的Leader。

  资源的配置信息★■■:包括各种对象的定义,如Deployment、StatefulSet、ConfigMap◆★◆◆■■、Secret等等,这些配置信息用于定义集群中的资源对象◆■■★◆◆,它们的Spec★◆◆、Label等等◆★★★◆。

  实时状态数据:etcd也存储了关于集群中各种资源对象的实时状态数据,这包括有关当前运行的pod的信息、资源对象状态★◆■■■、服务的端口映射等等,当这些对象的状态发生更改的时候,etcd会记录这些变化,以便K8S内部能获取到最新的状态信息◆★。

  k8s将容器放在pod中★★■■■,再通过scheduler将pod调度到对应的Node上运行,Node可以是一台物理机器◆★★■★,也可以是一台虚拟机器(云服务器)★◆■★,这取决于你所在的集群配置。每个节点包含着运行Pod所需的所有环节,而所有结点通过控制平面进行管理。

  路由控制器负责适当的配置云平台中的路由,以便不同节点上的容器可以相互通信。具体实现取决于各个云供应商,路由控制器也可能为Pod分配IP地址。

  工作结点:因为scheduler在调度pod的时候有自动调动策略,通常如果某个node失效◆■◆◆★,会自动将pod部署在其他node上,所以node结点我们无需额外处理■■◆★★★,只要集群拥有足够多的node结点,运行情况就会很稳定

  api-server、scheduler:负责接受请求 是一个无状态的服务,所以我们可以起多个api-server实例★★◆★◆◆,然后通过负载均衡器让请求均匀的打到所有的api-server上去,既能提高可用性◆◆◆,也能降低单个api-server的压力,提升请求处理速度