一文看懂 Container Runtime

Container Runtime 是 kubernetes 工作节点上的一个组件,运行在每个节点上。我们知道Kubernetes 是一个容器编排和管理引擎,所以 Container Runtime 至关重要。

如何正确理解Container Runtime?

当提到Container Runtime时,可能会想到许多例子: runc,lxc,Docker,containerd,cri-o。这些中的每一个都是针对不同情况而构建的,并实现了不同的功能。

有些Container Runtime(例如containerd和cri-o)实际上使用runc来运行容器,并且实现了镜像管理和API等高级特性。而 runc 也是一种Container Runtime。此时你可能有点不理解,为什么containerd和runc 都可以称为Container Runtime?

其实,通常只关注正在运行的容器的实际Container Runtime通常称为“low-level container runtimes”。支持更多高级功能(如镜像管理和gRPC/Web API)的运行时通常称为“high-level container runtimes”。我们需要重点知道的是,low-level container runtimes和high-level container runtimes是解决不同问题的不同的事物。

由于kubernetes 已经废弃了docker,所以本文我们讲到的Container Runtime 不再包括docker。kubernetes v1.22 版本之后,kubernetes官方 只支持 containerd 和 cri-o 两种high-level container runtimes。

实际应用中,low-level container runtimes和high-level container runtimes如下图所示,按照各自的分工,协作完成容器管理的工作。


其实high-level container runtime 是通过不同 shim 对接不同的low-level container runtime。比如 containerd 对接 kata-runtime:

low-level container runtime 几乎都是符合 OCI 规范的容器运行时,因而:

  • Kubernetes 只需支持 containerd 等high-level container runtime即可。由containerd 按照OCI 规范去对接不同的low-level container runtime,比如通用的runc,安全增强的gvisor,隔离性更好的runv。
  • 由于OCI 规范包含了 Image Spec,所以镜像是通用的。

Kubelet 如何对接Container Runtime?

上面已经提到,kubelet 真正对接的是 containerd 等 high-level container runtime,具体对接方式就是 Container Runtime Interface(CRI)。CRI 基于 gRPC 定义了 RuntimeService 和 ImageManagerService 两个 gRPC 服务,分别用于容器运行时和镜像的管理。

其中RuntimeService 需要实现以下接口方法:

// RuntimeService interface should be implemented by a container runtime.
// The methods should be thread-safe.
type RuntimeService interface {
	RuntimeVersioner
	ContainerManager
	PodSandboxManager
	ContainerStatsManager

	// UpdateRuntimeConfig updates runtime configuration if specified
	UpdateRuntimeConfig(runtimeConfig *runtimeapi.RuntimeConfig) error
	// Status returns the status of the runtime.
	Status() (*runtimeapi.RuntimeStatus, error)
}

ImageManagerService 需要实现以下方法:

/ ImageManagerService interface should be implemented by a container image
// manager.
// The methods should be thread-safe.
type ImageManagerService interface {
	// ListImages lists the existing images.
	ListImages(filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error)
	// ImageStatus returns the status of the image.
	ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi.Image, error)
	// PullImage pulls an image with the authentication config.
	PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error)
	// RemoveImage removes the image.
	RemoveImage(image *runtimeapi.ImageSpec) error
	// ImageFsInfo returns information of the filesystem that is used to store images.
	ImageFsInfo() ([]*runtimeapi.FilesystemUsage, error)
}

具体 Service 代码可以参阅 repo

例如containerd:

从 containerd V1.1开始,对CRI的支持以插件的形式内置在containerd中。它是默认启用的,但是可选的。 CRI插件通过containerd client 与containerd 进行交互。这种基于插件的体系结构既稳定又有效。该插件处理来自kubelet的所有CRI服务请求,并通过操作系统服务,CNI和containerd client API来管理Pod生命周期。这些containerd服务提取容器镜像,为容器创建运行时镜像(快照),并使用容器运行时环境(例如runc)随后创建,启动,停止和监视容器。

早些时候提出的CNI,CSI,CRI 三大接口规范,CNI 是最普及的,随着 in-tree 存储逐步移除,目前来说,CSI 也相当普及了。从Kubernetes v1.20 开始,CRI 接口规范也将大一统。

发展趋势

目前来看,CRI 和 high-level container runtime基本已经稳定。未来趋势更集中在low-level container runtime。事实上,从CNCF 容器运行时的全景图看出。

也许未来,容器运行时像一个琳琅满目的大超市,我们根据不同的使用场景选择不同的运行时。个人总结发展趋势有以下几个:

1:增强安全性

随着容器的大规模应用,安全问题也愈发突出。我们经常可以看到Pod中运行的程序获取了额外的权限,逃逸到主机,从而扩大了攻击面。解决容器安全,也成为一个刻不容缓的工作。在该点上,gvisor 提供了主机和应用之间更强的隔离,所以gvisor 实现的容器运行时称为runsc,顾名思义,安全的runc。

2:更好的隔离性

我们都知道runc 通过linux namespace 实现隔离。但是随着各家公有云提供了容器实例服务或是serverless,所有的用户的容器跑在一个大的资源池里,这就要求更好的隔离性。所以aws 推出了 firecracker ,社区推出了kata,这两种都是runv的思路。希望结合虚拟机的隔离性和容器速度。

3:更加轻量化

边缘计算日趋火热。像华为开源的kubeedge,阿里云开源的OpenYurt等边缘计算框架,均是基于”容器+kubernetes“实现的。受限边缘设备的有限资源,这就要求容器运行时必须轻量化。

4:WASM+WASI 是否会横空出世?

Docker 核心作者曾经说过,如果WASM+WASI 早点出现,压根没有docker什么机会了。docker的火爆我们已经体会到了。那么我们看看为什么WASM+WASI 可以替换掉docker?docker的优势在于镜像的分发(代码的分享,抹平了各种语言),隔离性(namespace和cgroup),而这两种正是wasi的优势,而且做的更好。沙箱的隔离方式,在安全性和隔离性上更胜一筹。

所以未来的架构可能是如下:

而且目前一些 serverless 厂商已经开始这方面的探索了,比如 secondstate 公司正在将 wasm 用于 faas,区块链,AI等领域。

编辑于 2020-12-20 00:12