容器技术常见概念介绍

1190阅读 0评论2023-06-18 lvyilong316
分类:LINUX

容器技术常见概念介绍

——lvyilong316

提起容器技术,大多数人肯定都会想起来dockerk8s等。但是随着对容器技术了解的越多,会接触到越来越多的名称,比如runCrunVkatagVisor等,有比如容器运行时,容器引擎等这些听着让人一脸雾水的名称,让人“剪不断,理还乱”。这篇文章就是将容器生态的一些概念进行归类整理,对这些名称的含义和定位大体做一下介绍。

首先容器技术包括容器镜像和容器引擎两部分,由于容器镜像相对比较独立,我们今天这里主要介绍执行引擎部分的概念。

按照官方的分层,容器管理系统分为三层:

1. High-level Container Management:容器管控的UI层。直接实现容器的管控和使用界面,也是用户{BANNED}最佳熟悉的子系统。

2. High-level Container Runtime:容器状态及资源供给。包括镜像管理、网络接入、容器状态、调用Low Level Runtime执行容器等功能。习惯上这层称之为容器引擎(Container Engine

3. Low-level Container Runtime:容器执行层。负责具体构建容器运行环境并执行容器进程。习惯上这层直接简称为容器运行时(Container Runtime

High-level Container ManagementContainer Engine之间的接口规范是CRIContainer EngineContainer Runtime之间的接口规范是OCI

按照我个人理解,将上述描述概括为如下图所示的三层。其中{BANNED}中国第一层管理UI不再介绍,这里主要介绍下面的两层:容器引擎和容器运行时。

 

容器引擎

容器引擎的核心是准备运行容器所需要的资源以及管理容器生命周期。在K8S生态圈中,容器编排系统通过CRI接口来调用容器引擎。支持CRI接口的容器引擎主要有docker、rkt、pouch、containerd和cri-o等,其中活跃度比较高的是containerd和CRI-O。

containerd

Containerd是从dockerd中抽离出来的容器管理的核心功能,是在社区影响下dockerd模块化的结果,也是现在{BANNED}最佳热门的容器引擎。由于containerd是从dockerd演化出来的,使用接口是针对容器管理而设计,内置管理对象是ImageContainerK8S CRI的管控对象是Image/Pod/Container,为了让containerd支持Pod对象以及实现CRI接口,引入了CRI-containerd组件来粘合Kubeletcontainerd两个子系统。现在cri-containerd组件已经作为一个功能模块内置到containerdContainerd依赖后端container runtime来具体管理容器,{BANNED}最佳常见的container runtimerunC

CRI-O

CRI-O则是专门支持K8S CRI接口而设计实现的容器引擎,它抛弃了对docker的支持而专注于支持K8S CRI,所以架构相对containerd要简洁不少。但是,虽然架构简洁优雅,但是从实际使用体验看CRI-O在成熟度、可扩展性方面相对cantainerd还是有一定差距。今年CRI-O也增加了对shimv2接口的支持,从而可以支持runC之外其它容器运行时,但是实际测试发现功能还不成熟。

通过上面介绍可以看出,容器引擎{BANNED}最佳终还是需要通过容器运行时来管理容器,下面来看容器运行时。

容器运行时

提起容器运行时(runtime),{BANNED}最佳熟悉的莫过于runC要理解runc,我们需要了解容器标准OCIOpen Container Initiative)可以理解为容器运行标准,是由多个组织共同成立,主要是维护runc的标准协议和相关的开发工作。所谓的runc主要是负责容器生命周期的管理,以及对容器状态的描述。runc的实现标准主要是根据OCI相关的规范来实现容器生命周期的管理,也是所有容器运行的基础功能。runc容器可以说实现了cgroup/linux kernel相关的隔离抽象接口。自从docker项目改为moby以后,dockerOCI标准抽出runc的项目,docker根据containerd直接调用了runcapi。总结,runc抽象出来的一个容器运行标准的api,主要是容器生命周期管理的一个项目。

看完是不是感觉一头雾水呢?这里runC也是管理容器生命周期的,那和上面容器引擎,如Containerd什么区别。借用下图可以大概描述,正如上文所述Containerd依赖后端container runtime来具体管理容器,当然中间还引入了一个shim。所以从功能上来说确实运行时和引擎是类似的,但是所处的层次不同。

至于为什么要有个shim,主要是为了允许容器退出不产生僵尸进程,以及接管容器的标准输入输出和打开的fd,{BANNED}最佳后就是作为容器的父进程向上汇报容器的退出码。所以可以理解为shim是在容器引擎和运行时之间的中间层。

但是运行时是不是理解为就是linux namespacecgroup这些呢?或者在安全容器中的底层虚拟化技术呢?其实也不是。这里面如果细分又要多一层,要区分runtime vmm。作为一个比较好的例子,我们来看下Kata

Kata Containers

出于对传统容器安全性的担忧,Intel 2015 年启动了它们以虚拟机为基础的容器技术:Clear ContainerClear Container 依赖 Intel VT 的硬件虚拟化技术以及高度定制的 QEMU-KVMqemu-lite)来提供高性能的基于虚拟机的容器。在 2017 年,Clear container 项目加入了 Hyper RunV,这是一个基于 hypervisor OCI 运行时,从而启动了 Kata 容器项目所以Kata便成为了runV的一个典型代表,类似docker之于runC

Kata containers {BANNED}最佳大的特点是它专注于实现一个开放的符合OCI标准的安全容器runtime实现,对于对接什么样的虚拟化方案,它抽象了一套hypervisor接口,如今已经对接了多种虚拟化实现,比如qemunemufirecrackercloud-hypervisor等。所以kata不是vmmkata原生的vmmqemu,但是也可以支持其他vmm。而我们通常所说的kata,更多的是指上层的shim

特别是2019年,Kata containers有个非常重要的技术进步,和containerd社区共同制定了shimv2接口规范,并率先在Kata containers支持了该规范。通过containerd-shim-v2vsock技术,kata精简了大量的组件,配合轻量级hypervisor和精简内核,kata可以大幅降低内存开销和容器启动时间。更关键的是,降低系统部署复杂度还大幅提高了稳定性,特别是在系统重载情况下的稳定性。如下图所示,我们通常说的kata是指图中的红色部分,和底层vmm无关。

Firecracker-containerd

FirecrackerAWS基于Google crosvm开发的、配合KVM使用的一个轻量级安全VMM,用以支持和实现MicroVMFirecracker MicroVM 同时具备传统虚拟机的安全性和工作负载隔离能力以及容器的速度和资源利用率。所以Firecracker是个vmm,它和kata不是一个层次的概念,相反它和qemu是一个层次的概念。而Firecracker-containerdfirecrackercontainerd的合体。或者说把containerdshimagent,和vmm进行了打包,也就是对容器引擎,runtimevmm进行了打包。所以当我们说Firecracker-containerd时,其实包括了容器引擎,runtimevmm

gVisor

Google gVisor GCP App EngineCloud Functions Cloud RunCloudML 中使用的沙箱技术,正式商用名称是Google SandboxGoogle 意识到在公有云基础设施中运行不受信容器的风险,以及虚拟机沙箱的低效,因此开发了用户空间的内核作为沙箱来运行不受信应用。gVisor是沿着libdune的系统调用拦截思路发展而来的用户态内核或进程虚拟化技术。gVisor 通过拦截所有从应用到主机内核的系统调用,并使用用户空间中 gVisor 的内核实现来处理这些调用。

所以,本质上来说,gVisor VMM 和客户内核的组合,或者说gVisorsyscall虚拟化。

runD

{BANNED}最佳后我们看一下阿里的runDrunD是一个整体的安全容器解决方案,解决了跨容器的重复数据、每个虚拟机的高内存占用和 host cgroup 的高开销问题。从架构方面是将vmmshim进行了打包,从技术上来说技术在runV的基础是通过一系列优化措施,如rootfs读写分离,guest内核精简,轻量级cgroup等技术,使容器满足安全隔离的前提下,更加轻量和高效。所以runD也可以理解为是一个runtime+vmm的打包。

上一篇:iotlb和ATS
下一篇:DPDK 22.11内存管理变化解析