多年锤炼,迈向Kata 3.0 !走进开箱即用的安全容器体验之旅| 龙蜥技术
文/云原生 SIG(Special Interest Group)
一、Kata 的过去
让我们将时钟拨回 2015 年 5 月,Hyper.sh 和 Intel 开源技术中心的工程师们分别独立发布了runV 和 Clear Containers 的虚拟化容器项目,而这两个项目便是 Kata Containers1 的前身。这两个项目互相有很多交流,在分别独立发展了两年半之后,于 2017 年底合并成了 Kata Containers 项目,并把这个项目捐给 Openstack 基金会管理,这也是 Openstack 基金会的第一个 Pilot 项目。在 2019 的 4 月,Kata Containers 被 Openstack 基金会认可为其第二个顶级项目,在这之前的十多年里,Openstack 基金会都只有 Openstack 一个顶级项目。
Kata Containers 安全容器的诞生解决了许多普通容器场景无法解决的问题:
1. 多租户安全保障。云原生多租户场景下,安全容器可以防止恶意租户对 host 内核的直接攻击并大幅减少机器上其他租户的风险,从而让公有云服务变得更稳定。
2. 不同 SLO 混部容器混合部署。安全容器的强隔离性减少了容器之间的性能影响,使得不同 SLO 优先级实例混部有了更稳定的技术方案,对延时敏感的在线业务用 runC 解决方案,大数据类对资源诉求比较高且有明显峰谷差异的离线业务用安全容器解决方案,防止离线业务突发流量影响到在线业务,通过在线离线业务同时混部进一步减少计算资源的浪费和成本消耗。
3. 可信&不可信容器混合部署。可信代码运行在 runC 容器中,不可信代码运行在安全容器中,两者在同一台宿主机上混部,降低不可信容器产生危害的可能性。
在这些优势的基础上,安全容器在虚拟化上追求极致的轻薄,从而让整体资源消耗和弹性能力接近 runC 容器方案,以此达到 Secure as VM、Fast as Container 的技术目标。
二、Kata 的发展
在 2018 年 5 月 Kata 1.x 阶段, Kata 和 containerd 社区共同制定了 shimv2 接口规范,并率先在 Kata Containers 支持了该规范。18 年11月,通过 containerd-shim-v2 和 vsock 技术,Kata 精简了大量的组件,配合轻量级 hypervisor 和精简内核,kata 可以大幅降低内存开销和容器启动时间。更关键的是,降低系统部署复杂度还大幅提高了稳定性,特别是在系统重载情况下的稳定性。
(图1/Kata 1.x 架构图)
2019 年的时候,Kata 从 1.x 升级到了 2.x , 有了非常重要的技术进步。Kata-agent 使用 Rust 进行了重构,极大程度减少了内存开销以及整体攻击面。
通过 2.x 版本,Kata 从最开始的做架构、用开源组件搭建原型的快速成长道路,逐渐有了名气,走向了影响上游社区技术迭代的成熟道路。而 Kata 的整体架构在 2.x 版本中已趋向成熟,后续发展需要开始对专用组件进行思考和优化,从而以局部影响整体来实现 Kata 能力的再次提升,例如 2.x 中用 Rust 改写 Kata agent 降低内存开销便是一个很好的例子。
而在 Kata 迅速发展的这几年间,阿里云内部有一个名为“袋鼠”的团队一直在基于 Kata 打造云原生场景下的秘密武器。
三、袋鼠云原生底层系统
为了解决由于云原生带来的高密、高并发等技术难题,阿里云内部用多年的时间锤炼了一套袋鼠云原生底层系统。袋鼠中的安全容器解决方案便是基于 Kata Containers 项目打造,并将其向更极致的方向深度优化,袋鼠做的优化诸如使用 Rust 重写了 Kata Container 2.0 的 go runtime 来进一步降低容器运行时的内存开销,并且为 Kata Container 专门开发了一个针对容器场景深度优化的轻量级虚拟机管理器Dragonball,通过容器运行时以及虚拟机一体的设计将 Kata 的整体体验带上了新的高度。
那么袋鼠安全容器都能提供什么样的能力呢?
简单来说便是极致的高密和弹性。
袋鼠安全容器可以在 6 秒之内弹出 3000 个安全容器,同时在一台机器上可以运行超过 4000 个以上的安全容器。通过袋鼠,我们成功支撑了阿里云的函数计算 FC 业务每日近 120 亿调用量,弹性容器实例 ECI 业务每日最高超百万的创建量,通过极致的性能表现大幅增加业务的核心竞争力。在极致性能之外,我们也通过使用安全容器进行混部,从而节省了大量资源成本。
袋鼠在内部取得的成绩与 Kata 社区的发展息息相关,因而袋鼠也决定将其多年来内部打磨的系统回馈到 Kata 社区,共同推进 Kata 社区的进一步发展。
四、Kata 3.0:袋鼠与 Kata 的一场碰撞
在云原生场景下,业界对容器启动速度、资源消耗、稳定性的要求越来越高,而这些也是安全容器相对普通容器会面临的挑战。仿若多年前 runV 和 Clear Containers 的交互诞生了 Kata Containers 这个顶级项目,多年之后的今天袋鼠与 Kata 之间彼此碰撞,袋鼠会将其基于 Kata 社区历经线上生产环境考验的内部系统开源到 Kata 社区,助力 Kata 社区架构升级至 3.0 版本,让 Kata 整体的使用体验、资源消耗、启动速度、稳定性都得到提升。
总结而言,在 Kata 3.0 版本中,我们将新增加了以下设计:
- 为了减少复杂的流程来和不同 VMM 适配,获得开箱即用的安全容器体验,我们提供了内置基于容器场景深度优化的 Dragonball 沙箱。Dragonball 将提供 Kata 安全容器生态下的虚拟化最优解。
(当然,Kata 3.0 的可扩展架构也支持用户通过配置选项使用其他 VMM,做出符合实际需求的决策。)
- 为了实现高性能、低资源利用、内存安全,以及高并发的目标,我们实现了 Async Rust Runtime 的新技术。
- 为了支持不同 Service、 Runtime 和 Hypervisor,以及增加机密容器的相关支持,为 Wasm 等未来方向留下空间,我们在 Runtime 内提供了可扩展框架来实现这一目标。
- 为了容器和沙箱资源生命周期统一管理机制,我们提供了 Resource Manager 机制来实现这一目标。
在本文的后续部分,我们会对 Kata 3.0 的重点更新进行展开。
五、设计介绍
(图2/Kata3.0 架构图)
5.1 内置 VMM Dragonball
Dragonball 沙箱是针对 Kata 量身打造的一个基于 KVM 的轻量级 VMM,除了支持常规的 hypervisor 的功能以外,还针对容器工作负载做了一些优化:
- 基于 Nydus2 开源项目的容器镜像管理和镜像加速服务
- 可扩展高性能的虚拟设备驱动
- 低 CPU 内存开销
- 单VM快速启动时间,多VM快速并发启动速度
为什么需要内置 VMM?
(图3/Kata2.x版本Runtime与VMM架构示意图)
如图所示,在 Kata2.x 之前 Runtime 和 VMM 是独立的进程。Runtime 进程会 fork VMM 进程并通过 RPC 进行交互。通常,进程之间的交互比进程内的交互会消耗更多的资源,从而会导致相对较低的效率。同时还要考虑资源运维成本,例如,在异常情况下进行资源回收时,任何进程的异常都必须被其他组件检测到,并激活相应的资源回收进程。如果有额外的过程存在,恢复变得更加困难。
并且,不同版本的 Kata 还需要考虑和不同版本的 VMM 的适配问题,可能 VMM 版本的落后或升级都会导致 Kata 适配上出现问题,需要用户花费额外的精力来做版本和配置上的调整。
最后,即使安全容器已经成为了业界多 SLO 混部/公有云多租户问题的标准解决方案,现在仍没有任何一款 VMM 是定位于支持安全容器生态的。其他 VMM 都有各自不同领域的定位,例如 QEMU 能力全面但代码已早早超越百万行,整体启动速度与消耗资源都偏大;Firecracker 虽然做到了极致轻薄但许多虚拟化能力都为了轻薄而做了减法,无法撑起安全容器复杂多变的场景需求。
多进程交互问题、运维复杂问题、VMM 版本适配问题、安全容器虚拟化缺位问题,都指向了一个共同的答案——我们需要一个专注于安全容器场景的 VMM 来提供安全容器生态下的虚拟化最优解。Dragonball VMM 便是带着这个使命而来的,在 Kata3.0 里,我们将提出一个内置于 Kata 生态的 Dragonball VMM,未来将与Kata 共同成长,以解决上文提到的这些历史问题。后续我们也会有专项文章对 Dragonball 进行介绍,敬请期待。
如何支持内置 VMM?
我们提供了 Dragonball 沙箱,通过将 VMM 的功能集成到 Rust 库中来启用内置的 VMM。我们可以通过使用该库来执行与 VMM 相关的功能。因为 Runtime 和 VMM 在同一个进程中,所以在消息处理速度和 API 同步方面具备优势。同时还可以保证 Runtime 和 VMM 生命周期的一致性,减少资源回收和异常处理维护,如图 4:
(图4/Kata3.0 内置VMM示意图)
5.2 可扩展框架
Rust 版本的 kata-runtime 为 Service、Runtime 和 Hypervisor 提供了可扩展框架,还包括了针对不同场景的配置逻辑。
- 在 API 层面,Service 提供了插件注册的机制来支持多种容器相关的原生服务。除了对容器进程进行管理的 task service, 后续还会增加 image 服务, 以及可以支持运维监控的其他服务。
- 支持不同类型的 Runtime 。包括基于虚拟化技术的 VirtContainer,基于可信计算硬件的机密容器。后面还会根据 kata 社区和行业需求考虑支持 WasmContainer 以及 LinuxContainer。
- 对于 VirtContainer 支持的 Hypervisor,除了内置的 Dragonball, 也可以插件式的去配置 Dragonball、Qemu、Acrn 以及 Firecracker。
5.3 资源管理
在我们的案例中,会有各种资源,每个资源都有相应的子类型。特别是对于 Virt-Container,每个子类型的资源都有不同的操作。并且可能存在依赖关系,例如 share-fs rootfs 和 share-fs volume 将使用 share-fs 资源将文件共享到 VM。目前,network 和 share-fs 被视为沙箱资源,而 rootfs、 volume 和 cgroup 被视为容器资源。因此,我们为每个资源抽象了一个公共接口,并使用子类操作来对应不同子类型之间的差异。
5.4 Rust Async Runtime
相对于 Go 语言, Rust 在性能和资源消耗方面更胜一筹,在某些特定的场景下效率甚至优于 C++。同时, Rust 还能避免空指针,野指针,内存泄露,内存越界等一些列内存安全问题, 从而大幅减少了程序崩溃的频率,这些能力对于 Kata 这种偏底层的系统尤为重要。然而 ,Go 语言的优势在于内置的机制和库来支持编写并发程序,比如 goroutine,以此显著降低 CPU 和内存开销,尤其是对于具有大量 I/O 密集型任务的工作负载。我们为了既兼顾 Go 语言的并发和异步优势,又获得 Rust 的安全性和低开销特点,开发了 Async Rust Runtime。
如何支持 Async?
kata-runtime 由 TOKIO_RUNTIME_WORKER_THREADS 控制运行 OS 线程,默认为 2 个线程。对于TTRPC 和容器相关线程统一运行在 tokio 线程中,相关依赖需要切换到 Async,比如 Timer、File、Netlink 等。借助 Async 我们可以轻松支持 non-block io 和计时器。目前,我们仅将 Async 用于 kata-runtime。内置的 VMM 保留了 OS 线程, 这样可以确保线程是可控的。
六、何为开箱即用?
让我们将注意力拉回到本文的标题——开箱即用的安全容器体验。通过上文的介绍,我们提到的“开箱即用”也应该在读者的心中逐渐清晰,在此我们对这个概念做以下总结:
通过提供内置于 Kata Runtime 的 Dragonball VMM 让安全容器整体生态的底层基础设施实现闭环,提供可扩展 Rust Runtime 来支持诸如机密容器等不同安全容器形态。从此之后,用户无需再做复杂的适配工作,只需下载 Kata、编译 Kata 即可运行 Kata,一切都将变得如此简单和易用。
这样开箱即用的体验,无论是对于初入 Kata 想快速上手的小白,还是商用 Kata 的工程师团队,都会带来易用性、可维护性、稳定性等多方面的提升飞跃,任何技术的发展一定是向更纯粹、更精简的方向前进,因而我们也坚信这会是 Kata 安全容器生态未来的方向。
七、未来展望
7.1 Kata 3.0 开发路线
目前, Kata 3.0 还处于第一阶段的开发,第一阶段将会完成 Kata 基本功能的实现。剩余的功能将会在第二和第三阶段陆续支持,预计在 2022-07-25 会有 Kata 3.0 的第一个 alpha 版本,欢迎各位参与到 Kata 3.0 的建设以及试用 3.0 版本。
Class | Sub-Class | Development Stage |
service | task service | 阶段 1 |
extend service | 阶段 3 | |
image service | 阶段 3 | |
runtime handler |
Virt-Container | 阶段 1 |
Wasm-Container | 阶段 3 | |
Linux-Container | 阶段 3 | |
Endpoint |
Veth Endpoint | 阶段 1 |
Physical Endpoint | 阶段 2 | |
Tap Endpoint | 阶段 2 | |
Tuntap Endpoint | 阶段 2 | |
IPVlan Endpoint | 阶段 3 | |
MacVlan Endpoint | 阶段 3 | |
MacVtap Endpoint | 阶段 3 | |
VhostUserEndpoint | 阶段 3 | |
Network Interworking Model |
Tc filter | 阶段 1 |
Route | 阶段 1 | |
MacVtap | 阶段 3 | |
Storage |
virtiofs | 阶段 1 |
nydus | 阶段 2 | |
hypervisor |
Dragonball | 阶段 1 |
Qemu | 阶段 2 | |
Acrn | 阶段 3 | |
CloudHypervisor | 阶段 3 | |
Firecracker | 阶段 3 |
7.2 Kata 3.0 发布时间
预计 2022-07-25 在 main 分支有可用的 alpha 版本,在此之前可先在开发分支 runtime-rs 使用 Kata 3.0。Kata 3.0 后续规划的发布时间与版本迭代进展我们也在此同步给各位。欢迎持续关注龙蜥社区公众号及龙蜥云原生 SIG,也欢迎感兴趣的小伙伴参与共建。
2022-07-25 | pre-release 3.0.0-alpha0 |
2022-08-15 | pre-release 3.0.0-alpha1 |
2022-08-29 | pre-release 3.0.0-alpha2 |
2022-09-12 | pre-release 3.0.0-rc0 |
2022-09-26 | pre-release 3.0.0-rc1 |
2022-10-10 | release 3.0.0 |
龙蜥云原生 SIG
在龙蜥云原生的首次 SIG 会议上,我们的架构师详细介绍了 Kata 3.0 原型 RunD 的技术架构,视频回放已上线至龙龙蜥社区官网(或点击阅读原文直达)和 B 站,欢迎对 Kata 3.0 想了解更多的小伙伴点击以下链接观看:
官网:https://openanolis.cn/video/B 站:https://www.bilibili.com/video/BV1jB4y1D7Yf?share_source=copy_web
同时,云原生 SIG 将整合龙蜥社区的云原生优势能力,输出开箱即用的龙蜥云原生发行版,结合用户需求输出大数据、混部等场景的解决方案,协助用户能更快更好使用云原生技术构建应用集群。Kata 作为龙蜥云原生的项目之一,未来也将共同构建基于安全容器的云原生服务。
后续 Kata 的能力我们会通过龙蜥社区云原生 SIG 上在整个云原生生态的视角上进行支持,欢迎感兴趣的同学们扫码加入龙蜥社区云原生 SIG 群(二维码见下),一起共建云原生生态。
相关链接:
[1] Kata Containers 项目链接:
https://github.com/kata-containers/kata-containers
[2] Nydus 项目链接:
—— 完 ——
加入龙蜥社群
加入微信群:添加社区助理-龙蜥社区小龙(微信:openanolis_assis),备注【龙蜥】与你同在;加入钉钉群:扫描下方钉钉群二维码。欢迎开发者/用户加入龙蜥社区(OpenAnolis)交流,共同推进龙蜥社区的发展,一起打造一个活跃的、健康的开源操作系统生态!
关于龙蜥社区
龙蜥社区(OpenAnolis)由企事业单位、高等院校、科研单位、非营利性组织、个人等在自愿、平等、开源、协作的基础上组成的非盈利性开源社区。龙蜥社区成立于 2020 年 9 月,旨在构建一个开源、中立、开放的Linux 上游发行版社区及创新平台。
龙蜥社区成立的短期目标是开发龙蜥操作系统(Anolis OS)作为 CentOS 停服后的应对方案,构建一个兼容国际 Linux 主流厂商的社区发行版。中长期目标是探索打造一个面向未来的操作系统,建立统一的开源操作系统生态,孵化创新开源项目,繁荣开源生态。
目前,Anolis OS 8.6 已发布,更多龙蜥自研特性,支持 X86_64 、RISC-V、Arm64、LoongArch 架构,完善适配 Intel、兆芯、鲲鹏、龙芯等芯片,并提供全栈国密支持。
欢迎下载:
https://openanolis.cn/download
加入我们,一起打造面向未来的开源操作系统!