0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Kubernetes架构和核心组件组成 Kubernetes节点“容器运行时”技术分析

454398 来源: Chinaunix 作者:lvyilong316 2020-09-25 15:53 次阅读

Kubernetes架构简介

Kubernetes架构如下图所示:

在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。

每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。

Kubernetes主要由以下几个核心组件组成:

1)etcd保存了整个集群的状态;

2)apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

3)controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

4)scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

5)kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;

6)Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);

7)kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

而和运行时紧密相关的就是kubelet。

kubelet架构

kubelet架构如下图所示:

kubelet是运行在每个节点上的主要的“节点代理”,每个节点都会启动kubelet进程,用来处理Master节点下发到本节点的任务,按照PodSpec描述来管理Pod和其中的容器(PodSpec是用来描述一个pod的YAML或者JSON对象)。kubelet通过各种机制(主要通过apiserver)获取一组PodSpec并保证在这些PodSpec中描述的容器健康运行。

容器运行时接口(CRI)

Kubernetes节点的底层由一个叫做“容器运行时”的软件进行支撑,它负责比如启停容器这样的事情。最广为人知的容器运行时当属Docker,但它不是唯一的。例如最近比较火热的安全容器KataContainer。所以也就很自然会与有一个需求,就是我们怎么去把KataContainer run在Kubernetes里?

那么这个时候我们还是先来看Kubelet在做什么事情,所以Kubelet要想办法像call docker一样去call KataContainer,然后由KataContainer负责帮忙把hypervisor这些东西set up起来,帮我把这个小VM运行起来。所以这个时候就要需要想怎么让Kubernetes能合理的操作KataContainers

对于这个诉求,就关系到Container Runtime Interface,我们叫它CRI。CRI的作用其实只有一个:就是它描述了对于Kubernetes来说,一个Container应该有哪些操作,每个操作有哪些参数,这就是CRI的一个设计原理(本质上是一堆ops)

Kubelet与容器运行时通信(或者是CRI插件填充了容器运行时)时,Kubelet就像是客户端,而CRI插件就像对应的服务器。它们之间可以通过Unix套接字或者gRPC框架进行通信。

protocol buffers API包含了两个gRPC服务:ImageService和RuntimeService。ImageService提供了从镜像仓库拉取、查看、和移除镜像的RPC。RuntimeSerivce包含了Pods和容器生命周期管理的RPC,以及跟容器交互的调用(exec/attach/port-forward)。一个单块的容器运行时能够管理镜像和容器(例如:Docker和Rkt),并且通过同一个套接字同时提供这两种服务。这个套接字可以在Kubelet里通过标识–container-runtime-endpoint和–image-service-endpoint进行设置。

下图显示了ImageService和RuntimeService具体需要实现哪些接口。

CRI Shim

CRI Shim可以做什么?它可以把CRI请求 翻译成Runtime API。我举个例子,比如说现在有个Pod里有一个A容器和有个B容器,这时候我们把这件事提交给Kubernetes之后,在Kubelet那一端发起的CRI code大概是这样的序列:首先它会run Sandbox foo,如果是Docker它会起一个infra容器,就是一个很小的容器叫foo,如果是Kata它会给你起一个虚拟机叫foo,这是不一样的。

所以接下来你creat start container A和B的时候,在Docker里面是起两个容器,但在Kata里面是在我这个小虚拟机里面,在这Sandbox里面起两个小NameSpace,这是不一样的。所以你把这一切东西总结一下,你会发现OK,我现在要把Kata run在Kubernetes里头,所以我要做工作,在这一步要需要去做这个CRI shim,我就想办法给Kata作一个CRI shim。

而我们能够想到一个方式,我能不能重用现在的这些CRI shim。重用现在哪些?比如说CRI containerd这个项目它就是一个containerd的CRI shim,它可以去响应CRI的请求过来,所以接下来我能不能把这些情况翻译成对Kata这些操作,所以这个是可以的,这也是我们将用一种方式,就是把KataContainers接到我的Containerd后面。这时候它的工作原理大概这样这个样子,Containerd它有一个独特设计,就是他会为每一个Contaner起个叫做Contained shim。你run一下之后你会看他那个宿主机里面,会run一片这个Containerd shim一个一个对上去。

而这时候由于Kata是一个有Sandbox概念的这样一个container runtime,所以Kata需要去match这些Shim与Kata之间的关系,所以Kata做一个Katashim。把这些东西对起来,就把你的Contained的处理的方式翻译成对kata的request,这是我们之前的一个方式。

但是你能看到这其实有些问题的,最明显的一个问题在于对Kata或gVisor来说,他们都是有实体的Sandbox概念的,而有了Sandbox概念后,它就不应该去再去给他的每一个Container启动有一个shim match起来,因为这给我们带来很大的额外性能损耗。我们不希望每一个容器都去match一个shim,我们希望一个Sandbox match一个shim

另外,就是你会发现CRI是服务于Kubernetes的,而且它呈现向上汇报的状态,它是帮助Kubernetes的,但是它不帮助Container runtime。所以说当你去做这个集成时候,你会发现尤其对于VM gVisorKataContainer来说,它与CRI的很多假设或者是API的写法上是不对应的。所以你的集成工作会比较费劲,这是一个不match的状态。

最后一个就是我们维护起来非常困难,因为由于有了CRI之后,比如RedHat拥有自己的CRI实现叫cri-o(基于Open Container Initiative的Kubernetes Container Runtime Interface的实现),他们和containerd在本质上没有任何区别,跑到最后都是靠runC起容器,为什么要这种东西?

我们不知道,但是我作为Kata maintainer,我需要给他们两个分别写两部分的integration把Kata集成进去。这就很麻烦,者就意味着我有100种这种CRI我就要写100个集成,而且他们的功能全部都是重复的。

Containerd ShimV2

为了解决以上的shim问题,引入了shimv2。前面我们说过CRI,CRI决定的是Runtime和Kubernetes之间的关系,那么我们现在能不能再有一层更细致的API来决定我的CRI Shim跟下面的Runtime之间真正的接口是什么样的?

这就是ShimV2出现的原因,它是一层CRI shim到Containerd runtime之间的标准接口,所以前面我直接从CRI到Containerd到runC,现在不是。我们是从CRI到Containerd到ShimV2,然后ShimV2再到RunC再到KataContainer。这么做有什么好处?

最大的区别在于:在这种方式下,你可以为每一个Pod指定一个Shim。因为在最开始的时候,Containerd是直接启动了一个Containerd Shim来去做响应,但我们新的API是这样写的,是Containerd Shim start或者stop。所以这个start和stop操作怎么去实现是你要做的事情。

例如KataContainers项目可以这么实现:在created Sandbox的时候call这个start的时候,我启动一个Containerd Shim。但是当我下一步是call API的时候,就前面那个CRI里面,Container API时候,我就不再起了,我是reuse,我重用为你创建好的这个Sandbox,这就位你的实现提供了很大的自由度。

所以这时候你会发现整个实现的方式变了,这时候Containerd用过来之后,它不再去care每个容器起Containerd Shim,而是由你自己去实现。我的实现方式是我只在Sandbox时候,去创建containerd-shim-v2,而接下来整个后面的container level操作,我会全部走到这个containerd-shim-v2里面,我去重用这个Sandbox,所以这个跟前面的时间就出现很大的不同。如下图所示是Kata1.5中采用shim v2的实现。

首先,你还是用原来的CRI Containerd,只不过现在装的是runC,你现在再装一个katacontainer放在那机器上面。接下来我们Kata那边会给你写一个实现叫kata-Containerd-Shimv2。所以前面要写一大坨CRI的东西,现在不用了。现在,我们只focus在怎么去把Containerd对接在kata container上面,就是所谓的实现Shimv2 API,这是我们要做的工作。而具体到我们这要做的事情上,其实它就是这样一系列与run一个容器相关的API。

比如说我可以去create、start,这些操作全部映射在我Shimv2上面去实现,而不是说我现在考虑怎么去映射,去实现CRI,这个自由度由于之前太大,造成了我们现在的一个局面,就有一堆CRI Shim可以用。这其实是一个不好的事情。有很多政治原因,有很多非技术原因,这都不是我们作为技术人员应该关心的事情,你现在只需要想我怎么去跟Shimv2对接就好了。

容器运行时总结

下图显示了当前主要的容器运行时和主要维护者。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 容器
    +关注

    关注

    0

    文章

    492

    浏览量

    22025
  • kubernetes
    +关注

    关注

    0

    文章

    223

    浏览量

    8682
收藏 人收藏

    评论

    相关推荐

    Kubernetes的Device Plugin设计解读

    至工作节点,到设备与容器的实际绑定。首先思考的第一个问题是为什么进入alpha.kubernetes.io/nvidia-gpu主干一年之久的GPU功能彻底移除?OutOfTree
    发表于 03-12 16:23

    Kubernetes之路 2 - 利用LXCFS提升容器资源可见性

    工具如free/top或遗留应用还依赖上述文件内容获取资源配置和使用情况。当它们在容器运行时,就会把宿主机的资源状态读取出来,引起错误和不便。LXCFS简介社区中常见的做法是利用 lxcfs来提供
    发表于 04-17 14:05

    容器开启数据服务之旅系列(二):Kubernetes如何助力Spark大数据分析

    + OSS on ACK,允许Spark分布式计算节点对阿里云OSS对象存储的直接访问。容器开启数据服务之旅系列(二):Kubernetes如何助力Spark大数据分析(二):
    发表于 04-17 15:10

    阿里云容器Kubernetes监控(一) - 资源监控

    分组中设置了所有节点核心组件的健康检查,健康检查状态出现问题时即可通过钉钉、邮件、短信的方式在第一件获取到Kubernetes的集群状态。对于版本在1.8.4及以上的老集群而言,可以
    发表于 04-23 14:35

    阿里云容器Kubernetes监控(一) - 资源监控

    分组中设置了所有节点核心组件的健康检查,健康检查状态出现问题时即可通过钉钉、邮件、短信的方式在第一件获取到Kubernetes的集群状态。对于版本在1.8.4及以上的老集群而言,可以
    发表于 04-23 14:35

    阿里云容器Kubernetes监控(一) - 资源监控

    分组中设置了所有节点核心组件的健康检查,健康检查状态出现问题时即可通过钉钉、邮件、短信的方式在第一件获取到Kubernetes的集群状态。对于版本在1.8.4及以上的老集群而言,可以
    发表于 04-23 14:35

    再次升级!阿里云Kubernetes日志解决方案

    Kubernetes日志采集方案如上图所示:K8S的每个worker 节点都会运行一个Logtail容器,该容器可采集宿主机以及该宿主机上其
    发表于 05-28 19:08

    不吹不黑,今天我们来聊一聊 Kubernetes 落地的三种方式

    现在让你选择一个容器管理平台,相信应该没人会错过 Kubernetes,尤其对于没有任何技术负担的用户,选择 Kubernetes 无疑是最明智的一个选择。Above
    发表于 10-12 16:07

    Kubernetes运行Kubernetes

    拍案叫绝的容器管理平台却迟迟未出现。 这样的局面一直维持到2014年,谷歌将 Kubernetes 项目发布到开放源代码社区之前。 Kubernetes 一开源,企业或者开发人员就可以在 Ku
    发表于 09-30 13:33 0次下载
    在<b class='flag-5'>Kubernetes</b>上<b class='flag-5'>运行</b><b class='flag-5'>Kubernetes</b>

    Kubernetes API详解

    摘要:Kubernetes是Google开源的容器集群管理系统。它构建Ddocker技术之上,为容器化的应用提供资源调度、部署运行、服务发现
    发表于 10-12 16:19 0次下载
    <b class='flag-5'>Kubernetes</b> API详解

    深入研究Kubernetes调度

    的大多方面。 Kubernetes Scheduler 是 Kubernetes 控制平面的核心组件之一。它在控制平面上运行,将 Pod 分
    的头像 发表于 08-23 10:39 1362次阅读

    带你快速了解 kubernetes

    节点,负责控制整个 kubernetes 集群。它包括 Api Server、Scheduler、Controller 等组成部分。它们都需要和 Etcd 进行交互以存储数据。 Api Server:
    的头像 发表于 01-17 10:00 1103次阅读

    Kubernetes中的逻辑组件

    Kubernetes是生产级别的容器编排系统,其物理集群有Master和Node两种类型的节点
    的头像 发表于 02-15 10:46 1180次阅读
    <b class='flag-5'>Kubernetes</b>中的逻辑<b class='flag-5'>组件</b>

    什么是Kubernetes容器运行时CRI

    起初,Docker是事实上的容器技术标准,Kubernetes v1.5之前的代码中直接调用Docker API,实现容器运行时的相关操作。
    的头像 发表于 02-20 16:22 1441次阅读
    什么是<b class='flag-5'>Kubernetes</b><b class='flag-5'>容器</b><b class='flag-5'>运行时</b>CRI

    kubernetes是什么,Kubernetes架构原理详解

    Kubernetes是一个基于容器技术的分布式集群管理系统。它是谷歌在大规模应用容器技术方面数十年经验的实际成果。因此,支持大规模的集群管理
    发表于 03-31 10:06 543次阅读