写点什么

InfoQ 极客传媒 15 周年庆征文|容器运行时技术深度剖析

作者:liuzhen007
  • 2022 年 6 月 11 日
  • 本文字数:2745 字

    阅读完需:约 9 分钟

摘要


容器技术作为云原生时代的核心内容,已经广泛使用在公有云、IDC 等各环境中。可是容器作为一种应用和资源隔离的技术,深入了解容器运行时隔离技术的原理和主流的运行时实现方式有非常重要的意义。今天我们在华为云云原生砖石课程的带领下,一起深度剖析容器运行时技术。


一、容器引擎和运行时机制原理剖析


容器技术作为云原生技术的核心组成部分,已经广泛使用在公有云、IDC 等各环境中。可是容器作为一种应用和资源隔离的技术,究竟它的实现原理是什么呢?它都有哪些不同的实现方式呢?我们究竟怎么定义“容器”呢?接下来,我们将深入容器技术的神秘面纱,揭开其背后的技术原理,给大家还原一个清晰的容器运行时技术全貌。


1. CRI 接口


CRI 接口是 kubelet 调用容器运行时的 grpc 接口。dockershim 是 kubernets 对接 docker api 的 CRI 接口适配器,kubernetes 1.21 版本已经将其标注为废弃接口。但是,这并不意味着 kubernetes 不再兼容 docker 容器。


CRI-containerd 是通过 containerd 中的 CRI 插件实现了 CRI 接口,让 containerd 可以直接对接 containerd 启动容器,无需调用 docker api。当前使用最为广泛的 CRI 接口实现。CRI-O 是专注于在 kubernetes 运行容器的轻量级 CRI 接口实现(不关注开发态)。



CRI 接口运行时接口负责容器的生命周期管理,包括容器创建、启动、停止、删除、日志和性能采集等接口。相关接口如下图所示:



CRI 镜像接口负责容器镜像的管理,包括显示镜像、拉取镜像、删除镜像、状态查询等接口。相关接口如下图所示:



2. OCI runtime spec 介绍


OCI 组织是 Linux 基金会于 2015 年 6 月成立的,全称是 Open Container Initiative。旨在围绕容器格式和运行时制定一个开放的工业化标准。目前主要有两个标准文档:容器运行时标准(runtime spec)和容器镜像标准(image spec)。


Runtime spec 是容器运行时标准,定义了容器状态和配置文件格式,容器生命周期管理命令和参数等。runc 是 docker 捐献给 OCI 社区的一个 runtime spec 的参考实现,docker 容器也是基于 runc 创建的。Kata-runtime 是一种基于虚拟化的安全隔离的 OCI runtime spec 的实现。gVisor 是一种基于系统调用拦截技术的轻量级安全容器实现。



Config.json 文件定义了容器运行所需的所有信息,包括 rootfs、mounts、进程、cgroups、namespaces、caps 等。


容器生命周期管理命令,包括创建、启动、停止、删除、状态查询等,示例命令如下:


1)创建容器命令格式:

# runc create <container id>


2)启动容器命令格式:

# runc start <container id>


3)容器状态查询命令格式:

# runc state <container id>


4)停止容器命令格式:

# runc kill <container id> <signal>


5)删除容器命令格式:

# runc delete <container id>


3. runtime v2


Shimv2 是新的容器运行时接口,基于 ttrpc 进行通信。其目的是让运行时更方便维护容器状态和生命周期,减少安全容器实现中节点的进程数和资源调用。


相关接口定义如下图所示:



4. RuntimeClass


RuntimeClass 是 kubernetes 中的对象类型,定义了集群中的某种运行时,并且可以通过 overhead 和 nodeSelector 定制某种运行时的资源和调度行为。


Runtime Plugin 是 containerd 中的 runtime 插件配置,定义了 runtime 名称、二进制路径、传递的 annotation、特权容器模式等。


RuntimeClassName 是 pod 中的字段,通过该字段可以决定用哪种运行时启动容器。具体配置信息可以参考下图:



二、 业界主流容器运行时技术架构剖析


1. Runc


runc 中的 Namespace 概念是用来隔离资源和信息的,通过 namespace 的隔离,容器中的应用只能看到分配到该容器的资源、其他主机上的信息在该容器中是不可见的。常用的 namespace 有 PID(进程号)、MNT(挂载点)、NET(网络)、UTS(主机名)和 IPC(进程间通信)等。


cgroups 用于资源使用量的隔离,通过 cgroup 限制了容器使用的资源量,通过不同的子系统,限制不同的资源,包括 CPU、内存、IO 带宽、大页、fd 数等。


capability 用于权限限制,通过对进程的 capability 定义,限制容器中的进程调用某些系统调用,以达到容器进程无法逃逸到主机的目的,比如容器中的进程是不是具有以下 capability:SYS_ADMIN、MKNOD、SYS_RESOURCE、SYS_MODULES 等。



容器进程对应的 namespace、capability mask 和主机进程对比的情况如下图所示(左边是容器进程,右边是主机进程):



2. kata containers


Kata container 是基于虚拟化来实现的容器隔离技术,具体特点和优势表现如下:


1)虚拟化隔离,每个 pod 都运行在一个独立的虚拟机中,提供虚拟化接口对接不同的虚拟化实现,包括 qemu、cloud hypervisor、firecracker 等。


2)轻量化,为了达到和容器近似的使用体验,需要对各组建进行裁剪,达到轻量化和启动加速的目的,对于 hypervisor,去除通用虚拟化的各种不必要的设备、总线等。对于 guest kernel,也裁剪了大量不需要的驱动和文件系统模块。而运行在虚拟机中的 1 号进程,一般为 kata-agent,资源占用可小于 1MB。


3)主机资源访问,通过 virtio、vfio 等方式访问主机资源,如 virtio-blk(块设备)、virtio-fs(文件)、virtio-net(网络)、vfio(物理设备)、vhost-user(用户态网络或者存储)。



3. gVisor


gVisor 是另外一种容器技术,主要是通过拦截系统调用实现的,主要特点如下:


1)虚拟内核,设置进程的 4 种模式,HR0、HR3、GR0、GR3,通过拦截系统调用,实现了一个虚拟内核,用户进程与 host kernel 不直接交互。


2)拦截系统调用,其实现方式有两种,分别是 ptrace 和 kvm。这种方式的优点是额外内存消耗小、容器启动速度快,但是也存在缺点,系统调用慢,导致 IO 和网络等性能较差,另外由于是模拟内核,可能会出现 POSIX 兼容性问题。



三、容器运行时技术的发展方向


未来容器运行时技术的发展方向有两个,一个是更轻量,一个是更安全。


轻量化方向,可以通过定制虚拟化和内核,提供更轻量的安全隔离方法;使用 sandbox plugin,去除 host 主机上的 shim;Rust 化,重写 hypervisor、kernel、agent 模块,减小内存占用。



更安全方向,基于虚拟化的机密计算,比如 TDX、SEV、PEF;镜像功能卸载,主机上看不到容器的依赖镜像;远程认证,确保运行在机密环境中。



总结


本文从 API 的角度介绍了 kubernetes 下容器运行时的架构和原理,介绍了当前较为热门的几种容器运行时的实现,可以选择基础型与增强型两种模式,最后谈了容器运行时未来的发展方向。通过 rust 重写、减少 host 进程,进一步轻量化 hypervisor 结合机密计算等方式实现更加轻量级的安全容器。



作者简介:😄大家好,我是 Data-Mining(liuzhen007),是一位典型的音视频技术爱好者,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解,😄公众号:玩转音视频。同时也是 CSDN 博客专家(博客之星)、华为云享专家(共创编辑、十佳博主)、51CTO 社区编辑、InfoQ 签约作者,欢迎关注我分享更多干货!😄

发布于: 刚刚阅读数: 5
用户头像

liuzhen007

关注

敲代码,搞开发。 2021.05.01 加入

本人深耕音视频技术,走全栈路线,前后端通吃,兼顾各端与流媒体服务器。 博客主页地址:https://liuzhen.blog.csdn.net 微信公众号:玩转音视频 欢迎交流学习!

评论

发布
暂无评论
InfoQ 极客传媒 15 周年庆征文|容器运行时技术深度剖析_容器_liuzhen007_InfoQ写作社区