k8s的容器运行时架构

容器运行时(ContainerRuntime),运行于 kubernetes(k8s)集群的每个节点中,负责容器的整个生命周期。其中dockershim是目前应用最广的容器运行时,随着容器云的发展,越来越多的容器运行时涌现。为了解决这些容器运行时和 k8s 的集成问题,在 k8s1.5 版本中,社区推出了 CRI(ContainerRuntimeInterface,容器运行时接口),以支持更多的容器运行时。

下图是k8s的容器运行时架构:

k8s的容器运行时架构_第1张图片

下图是k8s中容器运行时的执行逻辑:

k8s的容器运行时架构_第2张图片

CRI是kubernetes 定义的一组 gRPC 服务。Kubelet作为客户端,基于gRPC 框架,通过 Socket 和容器运行时通信。 它包括两类服务:镜像服务(ImageService)和运行时服务(Runtime Service)。镜像服务提供下载、检查和删除镜像的远程程序调用。运行时服务包含用于管理容器生命周期,以及与容器交互的远程调用。 OCI(OpenContainerInitiative,开放容器计划)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范(ImageSpecification)和运行时规范(RuntimeSpecification)。 镜像规范定义了OCI镜像的标准。高层级运行时将会下载一个 OCI 镜像,并把它解压成 OCI 运行时文件系统包。 运行时规范则描述了如何从 OCI运行时文件系统包运行容器程序,并且定义它的配置、运行环境和生命周期。如何为新容器设置命名空间(namepsaces)和控制组(cgroups),以及挂载根文件系统等等操作。

k8s弃用docker的原因 2020年底,Kubernetes官方发布公告,宣布自v1.20起放弃对Docker的支持,届时用户将收到 Docker 弃用警告,并需要改用其他容器运行时。但 Docker 作为容器镜像构建工具的作用将不受影响,用其构建的容器镜像将一如既往地在集群中与所有容器运行时正常运转。 这里面说到了容器运行时,其实k8s要弃用的是dockershim这个容器运行时,而非docker, dockershim是Kubernetes的一个组件,主要目的是为了通过CRI操作Docker,具体逻辑情况下图:

k8s的容器运行时架构_第3张图片

从图中可以看出,CRI、dockershim、docker直接的调用关系。dockershim存在的目的是为了Kubernetes通过CRI操作Docker,所以Kubernetes任何的功能变动或Docker有任何的功能特性变更,dockershim代码必须加以改动才能保证能够支持变更。 此外,Kubernetes去调用dockershim跟Docker做沟通,Docker的底层运行时是containerd,可以发现最终都是要调用containerd,并且containerd自身也是可以支持CRI的。那为什么要先绕过一层Docker呢?是不是可以直接通过CRI跟Containerd 进行交互呢?这也是现在Kubernetes社区希望弃用dockershim的原因之一。 Dockershim中间件会一直保留到2021年末,直到Kubernetes发布1.23版本时才完全移除。 不过,Kubernetes官方表示用户今后依然可以使用 Docker 来构建容器镜像,而Docker 生成的镜像实际上也是一个OCI(Open Container Initiative)镜像。无论使用什么工具来构建镜像,只要符合OCI标准的镜像在Kubernetes看来都是一样的。 那么,Dockershim废弃后,可替代它的容器运行时有哪些呢,最常见的有containerd和CRI-O.

dockershim、Containerd与CRI-O对比 下图是这三个运行时的详细调用层级:

k8s的容器运行时架构_第4张图片

Docker 的多层封装和调用,导致其在可维护性上略逊一筹,增加了线上问题的定位难度,Containerd 和 cri-o 的方案比起 docker 简洁很多。因此实际应用中更偏向于选用更加简单和纯粹的 containerd 和 cri-o 作为我们的容器运行时。 从功能性来讲,containerd 和 cri-o 都符合 CRI 和 OCI 的标准。从稳定性来说,cri-o没有足够的生产环境经验,而containerd一直在docker里使用,并且,docker的生产环境经验可以说比较充足。可见在稳定性上 containerd 略胜一筹。所以推荐大家选择containerd作为k8s的容器运行时。

你可能感兴趣的:(云原生,容器,docker,kubernetes)