Kubernetes节点的底层由一个叫做“容器运行时”的软件进行支撑,它负责比如启停容器这样的事情。最广为人知的容器运行时当属Docker,但它不是唯一的。事实上,容器运行时这个领域发展迅速。为了使Kubernetes的扩展变得更容易,我们一直在打磨支持容器运行时的K8s插件API:容器运行时接口(Container Runtime Interface, CRI)。

CRI是什么?

每种容器运行时各有所长,许多用户都希望Kubernetes支持更多的运行时。在Kubernetes 1.5发布版里,我们引入了CRI–一个能让kubelet无需编译就可以支持多种容器运行时的插件接口。CRI包含了一组protocol buffers,gRPC API,相关的库,以及在活跃开发下的额外规范和工具。CRI目前是Alpha版本。

支持可替换的容器运行时在Kubernetes中概念中并非首次。在1.3发布版里,我们介绍了rktnetes项目,它可以让rkt容器引擎作为Docker容器运行时的一个备选。然而,不管是Docker还是Rkt都需要通过内部、不太稳定的接口直接集成到kubelet的源码中。这样的集成过程要求十分熟悉kubelet内部原理,并且还会在Kubernetes社区引发巨大的维护反响。这些因素都在为容器运行时的初期造成了巨大的困难。我们通过提供一个清晰定义的抽象层消除了这些障碍,开发者可以专注于构建他们的容器运行时。这是很小的一步,但对于真正提供可插拔的容器运行时和构建一个更健康的生态系统却意义非凡。

CRI总览

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进行设置。

生命周期管理

对于Pod和容器的生命周期管理,CRI提供了下面的机制:

service RuntimeService {
// Sandbox operations.
rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}
// Container operations.
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}

}

在资源受限的隔离环境里的一组应用容器组成一个Pod。在CRI,这个环境被称为PodSandbox。我们故意留下一些空间,让容器运行时根据它们内部不同的原理来产生不同的PodSandbox。对于基于hypervisor的运行时,PodSandbox可能代表的是虚拟机。对于其他的,比如Docker,它可能是Linux命名空间。这个PodSandbox一定遵循着Pod的资源定义。在v1alpha1版API里,kubelet将创建pod级的cgroup限制下的一组进程,并传递给容器运行时,由此实现。

在Pod启动前,kubelet调用RuntimeService.RunPodSandbox来创建环境,包括为Pod设置网络(例如:分配IP)等。当PodSandbox启动后,就可以分别创建/启动/停止/移除独立的容器。为了删除Pod,kubelet会在停止和移除所有容器前先停止和移除PodSandbox。

Kubelet负责通过RPC来进行容器生命周期的管理,测试容器生命周期钩子和健康/可读性检查,同时为Pod提供重启策略。

容器为中心的接口

Kubernetes拥有对Pod资源的声明式API。我们认为一个可能的设计是为了使CRI能够在它的抽象里重用这个声明式的Pod对象,给容器运行时实现和测试达到期望状态的逻辑的自由。这会极大地简化API,并让CRI可以兼容更广泛的运行时。在早期的设计阶段我们讨论过这个方法,但由于几个原因否决了它。首先,Kubelet有许多Pod级的特性和特定的技术(比如crash-loop backoff逻辑),这会成为所有运行时重新实现时的巨大负担。其次,越来越重要的是,Pod的定义更新快速。只要kubelet直接管理容器,那么许多新特性(比如init container)不需要底层容器运行时做任何改变。CRI包含了一个必要的容器级接口,这样运行时就可以共享这些特性,拥有更快的开发速度。当然这并不意味着我们偏离了”level triggered”哲学。kubelet负责保证实际状态到期望状态的变化。

交互请求

service RuntimeService {

// ExecSync runs a command in a container synchronously.
rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {} // Exec prepares a streaming endpoint to execute a command in the container.
rpc Exec(ExecRequest) returns (ExecResponse) {} // Attach prepares a streaming endpoint to attach to a running container.
rpc Attach(AttachRequest) returns (AttachResponse) {} // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}

}

Kubernetes提供了一些用户可以与Pod及其内部容器进行交互的特性(例如kubectl exec/attach/port-forward)。Kubelet现在通过调用容器原生的方法或使用节点上可用的工具(例如nsenter和socat)来支持这些特性。在节点上使用这些工具不是一个可移植的好办法,因为这些工具的大部分假定Pod是通过Linux命名空间进行隔离的。在CRI,我们显式定义了这些调用,允许特定的运行时实现。

另外一个潜在的问题是,kubelet如今的实现是kubelet处理所有的流式连接请求。所以这会给节点的网络流量带来瓶颈。在设计CRI的时候,我们采纳了这个反馈,支持运行时防范中间人。容器运行时可以启动一个对应请求的单独的流服务器(甚至可能为Pod审计资源使用),并且将地址返回给Kubelet。Kubelet然后将这个信息再返回给Kubernetes API Server,它会打开直接与运行时提供的服务器相连的流连接,并将它跟客户端连通。

Kubernetes(k8s)容器运行时(CRI)的更多相关文章

  1. CRI 与 ShimV2:一种 Kubernetes 集成容器运行时的新思路

    摘要: 关于 Kubernetes 接口化设计.CRI.容器运行时.shimv2.RuntimeClass 等关键技术特性的设计与实现.     Kubernetes 项目目前的重点发展方向,是为开发 ...

  2. kubernetes/k8s CRI分析-容器运行时接口分析

    关联博客:kubernetes/k8s CSI分析-容器存储接口分析 概述 kubernetes的设计初衷是支持可插拔架构,从而利于扩展kubernetes的功能.在此架构思想下,kubernetes ...

  3. 使用kubeoperator安装的k8s 版本1.20.14 将节点上的容器运行时从 Docker Engine 改为 containerd

    官方文档:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/migrating-from-dockershim/change-runt ...

  4. Kubernetes容器运行时弃用Docker转型Containerd

    文章转载自:https://i4t.com/5435.html Kubernetes社区在2020年7月份发布的版本中已经开始了dockershim的移除计划,在1.20版本中将内置的dockersh ...

  5. 第28 章 : 理解容器运行时接口 CRI

    理解容器运行时接口 CRI CRI 是 Kubernetes 体系中跟容器打交道的一个非常重要的部分.本文将主要分享以下三方面的内容: CRI 介绍 CRI 实现 相关工具 CRI 介绍 在 CRI ...

  6. kubernetes(k8s)容器编排工具基础概念

    Kubernetes (K8s): 中文社区:https://www.kubernetes.org.cn/replication-controller-kubernetes 官网:https://ku ...

  7. kubernetes/k8s CSI分析-容器存储接口分析

    更多 k8s CSI 的分析,可以查看这篇博客kubernetes ceph-csi分析,以 ceph-csi 为例,做了详细的源码分析. 概述 kubernetes的设计初衷是支持可插拔架构,从而利 ...

  8. kubernetes/k8s CRI分析-kubelet创建pod分析

    先来简单回顾上一篇博客<kubernetes/k8s CRI 分析-容器运行时接口分析>的内容. 上篇博文先对 CRI 做了介绍,然后对 kubelet CRI 相关源码包括 kubele ...

  9. kubernetes/k8s CRI分析-kubelet删除pod分析

    关联博客<kubernetes/k8s CRI 分析-容器运行时接口分析> <kubernetes/k8s CRI分析-kubelet创建pod分析> 之前的博文先对 CRI ...

随机推荐

  1. ubuntu下的apache的虚拟主机的配置

    ubuntu下的虚拟主机的配置相对window下的虚拟主机配置有些许不同. 对于要新建的虚拟主机,我们可以有如下几个步骤: 1.在/etc/apache2/sites-available/目录下新建一 ...

  2. NServiceBus 概况

    NServiceBus 概况 NServiceBus 概况 NServiceBus 被设计用来组合面向业务的服务,它并不是用来替代诸如 WCF 一类的RPC技术. NServiceBus 不只包含通信 ...

  3. 在线web编辑器

    真正在线编辑的在线web编辑器 最近正在研究开发一款在线web编辑器架构,这是一款真正傻瓜式的web编辑器,可以在正常浏览页面的情况进行编辑,经过测试,对于一般网页页面来说非常好用方便,操作更简单. ...

  4. JS引擎

    在javax.script包下提供有关脚本引擎的类和接口,为我们定义了一系列的规范,达到可以在java应用程序中执行脚本语言编写的程序. javax.script包的主要功能有: 1.脚本执行:执行脚 ...

  5. 应用内支付(IAP)可加入三方支付

    Windows Phone 放开政策 - 应用内支付(IAP)可加入三方支付   Windows Phone 应用商店在 今年(2013)11月04号 修改了商店政策 允许公司账户的应用使用三方支付S ...

  6. Asp.Net中使用Couchbase——Memcached缓存使用篇

    Asp.Net中使用Couchbase——Memcached缓存使用篇 前言 在上一篇Asp.Net中使用Couchbase——Memcached缓存入门篇http://www.cnblogs.com ...

  7. SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY

    SCOPE_IDENTITY.IDENT_CURRENT 和 @@IDENTITY SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY.IDENT_CUR ...

  8. java的几种对象解释

    一.PO:persistent object 持久对象,可以看成是与数据库中的表相映射的Java对象.最简单的PO就是对象数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何数据 ...

  9. VS2003与Win7的兼容性问题

    VS2003并不官方支持Win7,目前大家遇到的主要是两个问题: 1. 在debug的时候,*.pdb文件在会被devenv.exe给lock住,当调适过一次之后,再进行编译的时候会有lnk1201的 ...

  10. Devexpress XtraReports 交叉报表

    [原创]Devexpress XtraReports 系列 5 创建交叉报表   昨天我们已经介绍了如何创建多栏报表,详见:[原创]Devexpress XtraReports 系列 4 创建多栏报表 ...