这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

codewiki上的介绍

Kuasar资料收集

1 - kuasar介绍

Kuasar sandbox 介绍

https://codewiki.google/github.com/kuasar-io/kuasar#introduction-to-kuasar-sandboxes


Kuasar 是一个多沙盒容器运行时,它统一了多种容器隔离技术于一致的 Sandbox API 框架下。它管理 MicroVM、App Kernel、WebAssembly(Wasm)和 runC 沙盒。这种做法在安全性和性能之间为云原生应用实现了平衡。

Kuasar 与容器运行时集成,特别是通过 containerdshim proxy 进行集成。这个代理充当 CRI runtime V2 backend ,在 containerd 和 Kuasar 的各种沙盒进程之间调解 Sandbox APITask API 请求。使用 Unix 域套接字(UDS)和 VSock 进行高效通信。更多详情请参考容器运行时集成。 Kuasar 提供不同的沙盒类型,每个都针对不同的隔离需求:

  • MicroVM Sandbox (VMM): 这个沙盒编排虚拟机环境,抽象设备管理、cgroup 控制、网络和存储。它通过在专用虚拟机中运行工作负载提供强隔离。
  • App Kernel Sandbox (Quark): quark-sandboxer 守护进程使用应用级虚拟机管理器管理容器化环境。这种设置利用定制内核优化性能。
  • WebAssembly Sandbox (Wasm): wasm-sandboxer 在 WebAssembly 运行时中启动容器,例如 WasmtimeWasmEdge 。这实现了 Wasm 模块的效率和可移植性执行。
  • runC Sandbox: runc-sandboxer 提供基于 runC 的容器功能,创建隔离的命名空间并管理容器生命周期。

单个居民 sandboxer 进程可以管理多个容器,采用 1:N 进程管理模型。与传统的 1:1 shim v2 模型相比,这减少了开销,并消除了 pause containers 。该项目使用 Rust 实现了许多组件,以提高效率和内存安全性。有关这些功能的更多信息,请参阅多沙盒功能概述和 Kuasar 的核心架构和设计原则。

Kuasar 沙盒介绍

Kuasar 是一个多沙盒容器运行时,旨在为各种部署场景提供云原生解决方案。它主要使用 Rust 实现,将多种容器隔离技术统一在一致的 Sandbox API 框架下,并借鉴了预览的 containerd API 的灵感。这种设计使 Kuasar 能够管理多种沙盒类型,包括 MicroVM、App Kernel、Wasm 和 runC 沙盒,在安全性、启动速度和标准化之间取得平衡。该项目的架构通过移除 pause containers 并采用 1:N 进程管理模型来优化性能,其中单个驻留的 sandboxer 进程可以管理多个容器,与传统 1:1 shim v2 模型相比,从而降低了开销。

Kuasar 的设计核心围绕几个关键组件和架构原则。它通过专门的沙盒器支持不同的隔离技术。例如,MicroVM 沙盒器( vmm-sandboxer ),位于 vmm 目录中,负责协调虚拟机环境,抽象设备管理、cgroup 控制、网络和存储。类似地,App Kernel 沙盒器( quark-sandboxer )在 quark 中,使用应用级虚拟机管理程序管理容器化环境。Wasm 沙盒器( wasm-sandboxer ),位于 wasm ,处理 WebAssembly 沙盒和容器,并与 WasmtimeWasmEdge 等运行时集成。最后, runC 沙盒器( runc-sandboxer )在 runc 中,管理基于传统 runC 的容器沙盒。

Kuasar 与容器编排系统的集成,特别是与 containerd 的集成,通过专门的 shim 实现。这些 shim 位于 shim 目录中,作为代理代理,在 containerd 和相应的 Kuasar 沙盒进程之间转发 Sandbox APITask API 请求。这种模块化设计确保 Kuasar 能够扩展其功能到不同的容器环境,同时保持与现有容器生态系统的兼容性。Kuasar 组件的整体构建、安装和测试过程由 MakefileMakefile 管理,以及位于 scripts 的补充脚本处理,从编译自定义 containerd 到配置超虚拟机和客户操作系统镜像,涵盖了所有方面。有关构建和安装的更多详细信息,请参阅构建和安装过程。

Kuasar 的核心架构和设计原则

Kuasar 是一个用 Rust 编写的有效容器运行时,旨在通过多种沙盒技术为各种场景提供云原生解决方案。其核心架构在一致的 Sandbox API 下统一了多种隔离技术,实现了安全、启动速度和标准化的平衡。

Kuasar 的一项基础设计原则是 Multi-Sandbox Colocation ,它允许不同的沙盒类型——MicroVM、App Kernel、Wasm 和 runC ——在单个节点上并发运行。这种方法使用户能够为他们的工作负载选择最合适的隔离级别。例如,MicroVM 沙盒提供强隔离,适合不可信的工作负载,而 runC 沙盒为可信应用提供轻量级的容器化。 Sandbox API ,正如 containerd 所预览的,作为统一接口,抽象掉了每种底层隔离技术的复杂性。这为容器运行时提供了一个一致的管理层,更多细节请参考容器运行时集成。

Kuasar 的 Optimized Framework 优先考虑性能和资源效率。一个关键的设计选择是移除 pause containers ,并将多个 shim 进程替换为单个驻留的 sandboxer 进程。这形成了一个 1:N 进程管理模型,其中单个 sandboxer 管理多个容器,与传统 1:1 shim v2 模型相比显著降低了开销。这种架构在不同沙盒类型中始终如一地实施。例如, vmm-sandboxer 编排虚拟机环境, quark-sandboxer 管理 App Kernel 沙盒, wasm-sandboxer 处理 Wasm 容器。这些沙盒器通过专用适配器与 containerd 通信,例如在 shim 中找到的适配器,它们转发 Sandbox APITask API 请求。该项目还维护一个路线图,概述了未来的增强功能和特性,表明持续关注优化和新功能。

整个 Kuasar 项目是用 Rust 语言实现的,这一选择强调了效率、内存安全性和并发性。这一点在主 (root) 目录中的源代码组织结构中表现得十分明显,其中核心组件、文档以及每种沙盒类型的工具都被系统地组织起来。在 MakefileMakefile 中,这些组件的构建、安装和测试被协调管理,展示了一个模块化和可配置的构建过程。该项目还致力于构建一个开放和中立生态系统,正如在 README.mdREADME.md 中所强调的那样,该生态系统旨在集成多样的沙盒技术并促进社区贡献,具体细节在 CONTRIBUTING.md 中有详细说明。

多沙盒功能概述

Kuasar 将多种隔离技术统一在一致的 Sandbox API 框架下,使多种沙盒类型能在单个节点上并发运行。这种方法在云原生环境中平衡了安全性、启动速度和标准化。其核心架构,如《Kuasar 核心架构与设计原则》所述,利用单个驻留的 sandboxer 进程来管理多个容器,通过移除 pause containers 优化资源使用并简化进程管理模型。

Kuasar 的多沙盒功能包括:

  • MicroVM Sandbox (VMM): 该沙盒利用开源虚拟机监视器(VMM)如 Cloud HypervisorQEMUStratoVirt 来协调虚拟机环境。 vmm-sandboxer 负责设备管理、cgroup 控制、网络和存储。在这些虚拟机中, vmm-task 组件作为 init 进程运行,管理容器和进程的生命周期。更多信息请参阅 微虚拟机沙盒( VMM
  • App Kernel Sandbox (Quark): quark-sandboxer 守护进程使用应用级虚拟机管理程序管理容器化沙盒环境。这种设置利用定制内核为应用内核工作负载提供优化性能。更多细节可在 应用内核沙盒( Quark 中找到。
  • WebAssembly Sandbox (Wasm): wasm-sandboxer 在 WebAssembly 运行时(如 WasmtimeWasmEdge )中启动容器。这使 Wasm 模块在容器化环境中能够高效和便携地执行。Kuasar 的 containerd-shim 集成特别利用这些运行时来执行 Wasm 模块和管理资源限制。更多信息请参阅 WebAssembly 沙盒( Wasm
  • runC Sandbox: runc-sandboxer 提供基于 runC 的容器功能,通过双重分叉机制创建隔离的命名空间。这些命名空间内的 runc-task 管理容器进程,确保与 OCI 规范兼容。更多详情请参阅 runC 沙盒

这些沙盒类型通过一个 shim 代理与 containerd 集成,该代理充当 CRI runtime V2 backend 。这个代理在 containerd 和相应的 Kuasar 沙盒进程之间转发 Sandbox APITask API 请求,使用 Unix 域套接字(UDS)和 VSock 进行进程间通信。有关此集成的详细说明,请参阅容器运行时集成。

构建和安装过程

Kuasar 的构建和安装过程主要通过一个 Makefile 和一套 shell 脚本进行协调,这些工具促进了其各种沙盒组件、定制容器运行时和客操作系统实体的编译和部署。该基础设施支持不同的虚拟机管理程序、WebAssembly 运行时和内核版本。

中央 MakefileMakefile )管理整个构建生命周期,包括编译 vmmwasmquarkrunc 沙盒器。它通过 HYPERVISOR (默认值为 cloud_hypervisor )、 GUESTOS_IMAGE (默认值为 centos )、 WASM_RUNTIME (默认值为 wasmedge )和 KERNEL_VERSION 等变量实现灵活配置。这些变量决定了构建哪些与 VMM 相关的组件、使用哪种类型的客户操作系统镜像以及集成特定的 WebAssembly 运行时。 Makefile 还负责将编译后的二进制文件和相关 systemd 服务文件安装到标准系统目录中。

Makefile 相补充, scripts 目录包含专门的 shell 脚本。 scripts/build 子目录专注于准备关键依赖。例如, build-containerd.shscripts/build/build-containerd.sh )自动化编译 Kuasar 特定的 containerd 二进制文件,并将其配置为与 Kuasar 的各种沙盒类型(如 kuasar-runckuasar-vmmkuasar-quarkkuasar-wasm )作为 proxy_plugins 集成。另一个脚本 cargo-vendor.shscripts/build/cargo-vendor.sh )通过为 Kuasar 的子项目提供 Rust 依赖,确保可重复构建,允许离线编译。

scripts/install 子目录提供了部署 Kuasar 的详细脚本,特别是 VMM 沙盒器。这些脚本针对不同场景,为 x86_64 和 aarch64 架构提供基于源代码的编译和基于二进制的安装。例如, build-and-install-kuasar-vmm.shscripts/install/build-and-install-kuasar-vmm.sh )通过编译 Cloud-Hypervisor (Kuasar VMM 沙盒器)、Kuasar 特有的 containerdvirtiofsd 从源代码进行完整安装。它还处理 crictl 的安装和配置,利用 Docker 或 Podman 等容器运行时进行隔离构建。为了在 x86_64 上更快部署, install-kuasar-vmm-x86.shscripts/install/install-kuasar-vmm-x86.sh )使用相同组件的预编译二进制文件。两种安装方法都包括下载组件的校验和验证,并提供交互式提示以获取用户确认。一个专门的 uninstall-kuasar-vmm.shscripts/install/uninstall-kuasar-vmm.sh )脚本提供了一种全面移除 Kuasar 相关组件的方式,包括停止 systemd 服务、删除二进制文件以及清理配置文件。

此外,VMM 组件在 vmm/scripts 中包含用于生成客机操作系统根文件系统和镜像的专业脚本。这涉及创建与 Kata Containers 兼容的镜像,并构建基于 CentOS 的根文件系统。 vmm/scripts/kernel 中的脚本用于为各种 VMM(如 Cloud Hypervisor、QEMU 和 StratoVirt)定制 Linux 内核镜像,并为 Kuasar 安全容器定制内核,通常针对最小内存占用进行优化。

文档与社区资源

Kuasar 提供了各种资源来促进理解、集成和社区参与。

docs 目录中提供全面的文档。这包括有关将 Kuasar 与 containerd 等容器运行时集成的详细指南,概述了 shim proxy 的功能以及 vmmquarkwasm 沙盒器的配置。还提供了针对不同虚拟机管理程序(如 QEMU 和 StratoVirt)构建、安装和配置 Kuasar 的具体说明。此外,文档还提供了在 Kubernetes 中部署基于 Wasm 的大型语言模型(LLM)推理应用程序的指导,展示了 Kuasar Wasm 能力的实际应用。

除了文档之外,该项目通过多种途径鼓励社区参与。 ROADMAP.md 文件概述了核心框架、测试、Kubernetes 功能支持和安全方面的未来开发计划及改进。贡献由 CONTRIBUTING.md 指导,其中详细说明了工作流程、代码审查过程和提交信息格式标准。 CODE_OF_CONDUCT.md 文件确立了社区期望,并参考了 CNCF 行为准则。 ADOPTERS.md 中提供了采用 Kuasar 的组织和项目的相关信息,而 MAINTAINERS.md 列出了官方项目维护者和团队。变更和版本历史计划在 CHANGELOG 目录中进行跟踪。

2 - 容器运行时集成

Kuasar 容器运行时集成

https://codewiki.google/github.com/kuasar-io/kuasar#container-runtime-integration


Kuasar 与容器运行时(特别是 containerd )通过一个专门的 shim proxy 进行集成。这个代理充当一个 CRI runtime V2 backend ,在 containerd 和 Kuasar 的各种沙箱进程之间中继请求。这个 shim 的主要功能是将 Sandbox API 请求转发到相应的 Kuasar 沙箱进程(例如 VMM 或 Wasm 沙箱进程),并将 Task API 请求转发到低级任务器,从而将复杂的处理工作从代理本身卸载。

shim 组件是使 containerd 能够协调 Kuasar 的多样化沙盒的核心,包括 MicroVMs ( kuasar-vmm ) 和 WebAssembly 模块 ( kuasar-wasm )。针对这些不同环境有特定的 shim 二进制文件,例如用于 MicroVMs 的 containerd-shim-kuasar-vmm-v2 和用于 Wasm 工作负载的 containerd-shim-kuasar-wasm-v2 。这些适配器被构建并安装到系统中,通常在 /usr/local/bin/ 中,使用位于 shim/MakefileMakefile 进行构建和安装。

containerd 与 Kuasar 沙盒进程之间的交互依赖于进程间通信机制。对于 kuasar-vmm ,通信通常通过 VSock 进行,这适用于虚拟化环境。对于 kuasar-wasm ,通常使用 Unix 域套接字(UDS)进行高效通信。 shim 负责建立和管理这些通信通道。

要集成 Kuasar 与 containerd ,需要在 containerd 的配置文件中进行特定修改,该文件通常位于 /etc/containerd/config.toml 。这些修改定义了 runtime_typesandbox_mode 设置,用于 kuasar-vmmkuasar-wasm 运行时,指定 containerd 如何调用 Kuasar 的 shims。此外,必须使用 ENABLE_CRI_SANDBOXES=1 环境变量启动 containerd ,以启用 containerd Sandbox API ,这对 Kuasar 的运行至关重要。

提供有关构建、安装和配置 Kuasar shimcontainerd 的全面指南,详细说明了先决条件和必要的系统调整。有关 shim 内部结构的更多详细信息,请参阅 Shim 代理架构和通信机制。

代理架构和通信机制

Kuasar shim 作为 CRI runtime V2 backend ,在 containerd 和 Kuasar 的 sandboxer 进程之间进行通信中介。这种架构允许 containerd 通过一致接口管理多样化的 Kuasar 沙盒,包括 MicroVM 和 WebAssembly (Wasm) 环境。Shim 主要作为代理,将 Sandbox API 请求转发到相应的 sandboxer (例如 vmm-sandboxerwasm-sandboxer ),将 Task API 请求转发到低级的 tasker ,从而最小化 Shim 对这些请求的内部处理。

沙盒的核心功能通过 Service<T> 结构实现,该结构遵循 Shim 特性。这个 Service 包含一个 KuasarServer<T> ,封装了与 Kuasar 组件交互的业务逻辑。这个 KuasarServer 又包括一个用于沙盒操作的 SandboxHandler<T> 和一个用于管理任务的 TaskHandler

containerdshim 以及 Kuasar 的 sandboxertasker 进程之间的进程间通信(IPC)通过不同的传输机制实现。对于 VMM 工作负载, containerd-shim-kuasar-vmm-v2 利用 VSockTransport ,实现通过虚拟套接字进行通信,这在虚拟化环境中很常见。这对于使用 MicroVMs 隔离容器的场景尤其相关。 shim/src/io.rs 中的 VSockTransport 管理虚拟套接字端口分配以防止冲突,并处理 containerd 管道和虚拟套接字流之间的数据传输。

对于 Wasm 工作负载, containerd-shim-kuasar-wasm-v2 采用 UdsTransport (Unix 域套接字)。这适用于 Wasm 沙盒可能不需要完整虚拟机的情况,可在主机系统内部提供高效的 IPC。 shim/src/io.rs 中的 UdsTransport 直接使用提供的管道路径, containerd 负责 UDS I/O 复制。

两个 shim 都建立与 Kuasar sandboxertasker 进程的连接。 shim/src/sandbox.rs 中的 SandboxHandler 负责将 containerd-shim TTRPC 请求转换为 containerd-sandbox v2 控制器的 gRPC 调用,管理从创建到关闭的沙盒的完整生命周期。 shim/src/task.rs 中的 TaskHandler 作为代理,将 containerd 垫片 Task API 调用转发到底层 TaskClient ,并与 SandboxHandler 协调容器和进程生命周期管理以及资源分配。这种架构确保了 containerd 可以无缝地与 Kuasar 的各种沙盒技术交互。有关 containerd 集成的更多详细信息,请参阅容器运行时集成。

构建与安装 Kuasar Shim

Kuasar containerd shim 通过位于 shim/MakefileMakefile 进行构建和安装。这个 Makefile 协调编译和安装两个不同的 shim 二进制文件: containerd-shim-kuasar-vmm-v2containerd-shim-kuasar-wasm-v2 。这些二进制文件使 containerd 能够分别与 Kuasar 的 VMM 和 Wasm 运行时集成。构建过程利用 cargo build --release 创建优化的可执行文件。构建完成后, install 目标将这些二进制文件移动到系统的 /usr/local/bin/ 目录,确保它们对 containerd 可用。

与 shim 构建互补,Kuasar 项目还包含一个用于构建自定义 containerd 二进制文件的脚本。该脚本位于 scripts/build/build-containerd.sh ,克隆 containerd 仓库的 Kuasar 特定分支,进行编译,并生成 config.toml 文件。此配置文件对于集成 Kuasar 运行时至关重要,它定义了 runtime_type 的设置,用于 kuasar-runckuasar-vmmkuasar-quarkkuasar-wasm ,并配置 proxy_plugins 以促进与各自的沙盒服务通信。这种自定义的 containerd 设置对于确保 shim 能够正确地与 Kuasar 的多沙盒功能交互至关重要。若要深入了解这些 shim 如何与 containerd 集成,请参阅 Kuasar 运行时的 Containerd 配置。

shim 服务和沙盒/任务管理

Kuasar 中的 containerd shim 服务充当关键的中介,将来自 containerd 的请求转换为由 Kuasar 的沙盒器和任务服务管理的操作。该服务主要由 Service<T> 结构实现,该结构遵循 containerdShim 特性。 Service<T> 利用一个 KuasarServer<T> 实例来封装与 Kuasar 后端交互所需的应用逻辑。

KuasarServer<T> 的核心包含两个关键组件: SandboxHandler<T>TaskHandlerSandboxHandler<T> 负责协调沙盒的生命周期。当 containerd 请求创建、启动、停止或删除沙盒等操作时, SandboxHandler 接收这些 TTRPC 请求,并将它们转换为对 containerd-sandbox v2 控制器的相应 gRPC 调用。这种委托确保实际的沙盒管理,包括资源分配和隔离,由 Kuasar 沙盒器处理。 SandboxHandler 还管理沙盒的本地文件系统设置和清理,例如创建根目录和挂载共享内存,具体细节请参见沙盒状态管理和持久化。

同样地,TaskHandler 负责管理沙箱内任务(容器和进程)的生命周期。它充当代理角色,将 containerd 适配层的任务 API 调用转发至底层的 TaskClient,后者再与 Kuasar Task Service 进行通信。当 containerd 请求创建、启动或删除容器或进程时,KuasarServer 中的 TaskHandler 会拦截这些请求。例如在容器创建请求中,它首先通过 SandboxHandler 准备沙箱环境,接着使用 ContainerIoTransport 配置 I/O 流,最后将任务创建委托给 TaskClient。该架构确保所有容器和进程操作(包括 I/O 管理)均由 Kuasar 任务服务协调执行,并通过 gRPC 实现进程间通信。关于 containerd 如何配置以与这些 Kuasar 运行时交互的具体细节,详见《Kuasar 运行时的 containerd 配置指南》。

Kuasar 运行时的 Containerd 配置

# /etc/containerd/config.toml

# ... other containerd configurations ...

[plugins."io.containerd.grpc.v1.cri"]
  # ... other CRI plugin configurations ...
  disable_apparmor = true # Important: AppArmor is not supported, must be true

  [plugins."io.containerd.grpc.v1.cri".containerd]
    # ... other containerd configurations within CRI plugin ...

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kuasar-vmm]
      runtime_type = "io.containerd.kuasar-vmm.v2"
      sandbox_mode = "shim"

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kuasar-wasm]
      runtime_type = "io.containerd.kuasar-wasm.v2"
      sandbox_mode = "shim"

# ... rest of the config.toml ...

将 Kuasar 与 containerd 集成需要对 containerd 配置文件进行特定修改,该文件通常位于 /etc/containerd/config.toml 。这些修改定义了 containerd 如何与 Kuasar 的各种沙箱运行时进行交互。Kuasar shim 充当 CRI runtime V2 backend 负责协调这种通信,详情请参阅 “容器运行时集成”部分

对于 kuasar-vmm (MicroVM)和 kuasar-wasm (WebAssembly)运行时,需要配置 containerd runtime_type 和 sandbox_mode 设置。对于 kuasar-vmm ,需要将 runtime_type 设置为 “io.containerd.kuasar-vmm.v2” , sandbox_mode 设置为 “shim” 。类似地,对于 kuasar-wasm , runtime_type 设置为 “io.containerd.kuasar-wasm.v2” , sandbox_mode 也相同。此配置的示例可在 docs/shim/README.md 中找到。

除了这些运行时特定的设置之外, containerd 中的 AppArmor 功能不受 Kuasar 支持,因此需要配置项 disable_apparmor = true 。此外,要启用 containerd 的 Sandbox API ,必须使用环境变量 ENABLE_CRI_SANDBOXES=1 启动 containerd 。此环境变量对于 containerd 正确使用 sandbox_mode = “shim” 设置并将沙箱管理委托给 Kuasar 至关重要。

安装脚本(例如 scripts/install/build-and-install-kuasar-vmm.sh 和 scripts/install/install-kuasar-vmm-x86.sh )会自动将系统中的 containerd 二进制文件替换为 Kuasar 兼容版本,并将 Kuasar 特有的 config.toml 文件复制到 /etc/containerd/config.toml ,其中包含必要的配置。另一方面, uninstall-kuasar-vmm.sh 脚本可以根据需要删除这些配置以及 Kuasar 特有的 containerd ,具体说明请参见 scripts/install/README.md 。

3 - MicroVM 沙箱

Kuasar MicroVM 沙箱

https://codewiki.google/github.com/kuasar-io/kuasar#microvm-sandbox-vmm


Kuasar 的 MicroVM (VMM) 沙箱实现利用虚拟机技术,为容器工作负载提供了一个强大且隔离的环境。这项功能是 Kuasar 多沙箱方法的核心,它在提供强大隔离保障的同时,还能保持性能。VMM 沙箱为每个沙箱编排一个虚拟机,抽象化了复杂的设备管理、cgroup 控制、网络和存储配置。这种抽象化使得容器能够在专用的虚拟机中运行,从而确保它们与其他容器和宿主机系统完全隔离。

VMM 沙箱环境的核心由几个关键组件构成。 vmm-sandboxer 组件负责协调虚拟机的生命周期,包括启动、停止和管理这些 microvm 的资源。在每个客户虚拟机内部,一个名为 vmm-task 轻量级进程以进程 ID 1 运行。该 vmm-task 负责管理客户虚拟机内部的容器和进程生命周期,处理资源分配、网络配置和异步 I/O 操作。主机与客户虚拟机的 vmm-task 之间的通信主要依赖于基于 vsock ttrpc ,从而实现高效的进程间通信,而无需将客户虚拟机的网络暴露给主机。

为了支持各种虚拟机管理程序,例如 Cloud Hypervisor、QEMU 和 StratoVirt,Kuasar 的 VMM 沙箱提供了灵活的集成机制。这包括针对特定虚拟机管理程序的客户端 API 和生命周期管理。该系统还支持针对这些不同的 VMM 和 Kuasar 安全容器对 Linux 内核镜像进行广泛的定制。这种定制(详见“微型虚拟机的 Linux 内核定制” 小节)通常侧重于优化内核以实现最小的内存占用,并根据具体用例将其分为 micro-kernel 或 mini-kernel 。

创建客户操作系统环境涉及多个构建过程。这包括构建客户操作系统根文件系统和镜像、编译 vmm-task 和 runc 二进制文件,以及配置 NVDIMM/DAX 头文件以优化性能。这些过程由脚本协调,以确保客户环境为容器执行做好充分准备。

VMM 沙箱利用过程宏简化了从 Rust 结构体生成命令行参数的过程,从而增强了可配置性和可维护性。这些宏将结构化的 Rust 数据转换为结构化的参数对象或原始命令行参数字符串,方便对虚拟机管理程序和客户机环境进行动态配置。更多信息,请参阅 “使用过程宏派生命令行参数”。

总的来说,Kuasar 的 VMM 沙箱为安全隔离的容器执行提供了一个强大而灵活的解决方案,它通过其 shim proxy 架构与现有的容器运行时(如 containerd 紧密集成,如容器运行时集成中所述。

VMM 编排和 Hypervisor 集成

Kuasar 通过其核心组件 KuasarSandboxer 和 KuasarSandbox ,协调虚拟机 (VM) 沙箱环境,抽象化设备管理、cgroup 控制、网络和存储。该架构支持与各种 Hypervisor(例如 Cloud Hypervisor、QEMU 和 StratoVirt)集成,每种管理程序都由特定的客户端 API 和生命周期管理提供支持。

定义在 vmm/sandbox/src/sandbox.rs 中的 KuasarSandboxer 和 KuasarSandbox 结构体分别实现了 Sandboxer 和 Sandbox 特性,用于管理 KuasarSandbox 实例、其虚拟机和容器的集合。KuasarSandboxer 负责整个沙箱的创建、启动、停止、删除和恢复。 KuasarSandbox KuasarSandboxer 一个基于虚拟机的沙箱,负责管理其 vm 、容器、网络配置以及与 SandboxServiceClient 通信。这包括诸如持久化和恢复沙箱状态、初始化 ttrpc 连接、在虚拟机内设置沙箱以及同步时钟等操作。

不同的虚拟机管理程序实现,包括 Cloud Hypervisor( vmm/sandbox/src/cloud_hypervisor 中的 CloudHypervisorVM 、 CloudHypervisorVMConfig 和 ChClient )、 QemuVM ( vmm/sandbox/src/qemu 中的 QemuVMConfig 、 StratoVirtVM 和 QmpClient )以及 StratoVirt( vmm/sandbox/src/stratovirt 中的 StratoVirtVM、 StratoVirtVMConfig 和 QmpClient ),提供了特定的 VM 和配置结构。这些实现定义了用于创建虚拟机实例 Hooks VMFactory 接口,以及用于启动、停止、挂载、分离和健康检查等操作的 VM 接口。Hooks 特性允许在虚拟机生命周期中注入自定义逻辑,例如 pre_start 和 post_start 操作,而 Recoverable 特性则允许在重启后恢复虚拟机状态。

设备管理由通用的 Device 和 Bus 特性抽象化,这些特性定义在 vmm/sandbox/src/device.rs 文件中,块设备、网络设备和控制台的具体实现则位于相应的虚拟机管理程序目录中。例如, vmm/sandbox/src/cloud_hypervisor/devices 管理 cloud_hypervisor 的设备。类似地,资源隔离的 cgroup 控制由 vmm/sandbox/src/cgroup.rs 处理,该文件提供了创建分层 cgroup、应用资源限制和分配进程的功能。网络配置(包括 NetworkInterface 和 IP 地址管理)在 vmm/sandbox/src/network 目录中进行管理,而存储连接则由 vmm/sandbox/src/storage 进行管理。

这些 VMM 沙箱的命令行参数源自 Rust 结构体,并使用了诸如 CmdLineParams 和 CmdLineParamSet 之类的过程宏,详情请参阅“使用过程宏派生命令行参数” 一文,从而能够动态生成 cloud-hypervisor 和 virtiofsd 的参数。每个 VMM 后端的 KuasarSandboxer 入口点位于 vmm/sandbox/src/bin 目录下,负责协调参数解析、配置加载(例如, vmm/sandbox/src/config.rs 中的 Config::load_config )、跟踪、信号处理和状态恢复。

客户端与沙箱服务的通信由位于 vmm/sandbox/src/client.rs 中的 SandboxServiceClient 管理,它支持 ttrpc 连接,并支持多种套接字类型(Unix、VSock、HVSock),用于执行诸如健康检查、沙箱设置和时钟同步等操作。关于 ttrpc 协议和代码生成等整体架构,包括如何从 protobuf 定义生成 Rust 代码,在 “TTRPC 协议和代码生成”一节中有更详细的阐述。

Guest OS 镜像和根文件系统生成

在 Kuasar 中构建客户操作系统根文件系统和镜像的过程涉及多个精心编排的步骤,旨在为各种虚拟机监控器 (VMM) 创建定制环境。主要的编排工作由 vmm/scripts/image/build.sh 脚本负责,该脚本管理根文件系统的创建,并可选择性地生成 initrd 或完整的可引导镜像。此脚本支持不同的容器运行时环境,包括 containerd 、 docker 和 isulad ,以便在容器化环境中执行根文件系统构建过程。

为了构建完整的与 Kata Containers 兼容的根文件系统镜像,需要使用 vmm/scripts/image/build_image.sh 中的脚本。该脚本会验证根文件系统,计算最佳磁盘大小,使用 qemu-img 创建原始磁盘镜像,并使用 parted 对其进行分区。然后,它会格式化根分区(支持 ext4 或 xfs ),复制根文件系统的内容,并在启用 AGENT_INIT 时优化 systemd 组件以减小镜像大小。一个值得注意的特性是可以使用 nsdax 工具配置 NVDIMM/DAX 标头,该工具会插入特定的元数据以启用支持 pmem 的 NVDIMM 设备功能。

基于 CentOS 的根文件系统使用 vmm/scripts/image/centos/build_rootfs.sh 中的脚本构建。此过程包括构建 Kuasar 的 vmm-task 二进制文件、安装 Go 运行时环境、编译 runc 二进制文件,然后将这些组件以及必要的 glibc 库和列表中指定的其他 RPM 包填充到一个临时根文件系统目录中。许多常用的构建工具(例如用于构建 vmm-task 和 runc 工具)集中在 vmm/scripts/image/common.sh 中,从而提高了模块化程度,并允许在不同根文件系统构建中重复使用。Rust 工具链( vmm-task 的依赖项)的安装由 vmm/scripts/image/install_rust.sh 处理,该脚本确保安装 rustup 并添加用于交叉编译的 unknown-linux-musl 目标。

nsdax 工具(实现于 vmm/scripts/image/nsdax.gpl.c )对于配置 NVDIMM/DAX 头部至关重要。该 C 工具会将 PFN(页帧号)元数据块嵌入到 NVDIMM 镜像文件中。该元数据块基于 Linux 内核 NVDIMM 驱动程序,包含数据偏移和对齐等信息,使内核能够正确解析 NVDIMM 区域。该工具的 main 功能是解析命令行参数,初始化 nd_pfn_sb 结构,使用 nd_fletcher64 和 nd_sb_checksum 计算其校验和,并将该结构写入镜像中的特定偏移量 ( SZ_4K )。这样就实现了双主引导记录 (MBR) 设置,支持 DAX 的系统可以读取第二个 MBR,而其他系统则读取第一个 MBR。

针对 microvm 的 Linux 内核定制

Kuasar 项目包含一个专用框架,用于构建和定制适用于各种虚拟机监控器 (VMM) 和安全容器的 Linux 内核镜像。该流程强调一种“添加式”定制方法,旨在最大限度地减少内存占用和冷启动时间。与从完整的内核配置开始并移除功能不同,该方法选择性地添加必要的功能,从而可以精确控制内核的资源消耗和性能。

内核定制框架主要在 vmm/scripts/kernel 目录下管理,支持多种虚拟机管理程序 (VMM),包括 Cloud Hypervisor、QEMU 和 StratoVirt,以及 Kuasar 安全容器。 vmm/scripts/kernel/build-kernel/build-kernel.sh 脚本负责协调此过程,根据目标架构和内核类型动态选择配置片段。它使用内核构建系统工具将这些片段合并,从而在编译前生成最终的 .config 文件。

支持两种主要的定制内核类型:

  • micro-kernel :专为无服务器和轻量级虚拟机设计,这些内核优先考虑最小的内存开销和低延迟,通常采用 MMIO 总线结构。

  • mini-kernel :这些内核提供更复杂应用程序所需的高级功能,例如 ACPI、SCSI、NFS 和对内核模块的支持,通常使用 PCI 总线结构。

kernel 目录中的特定构建脚本处理每个虚拟机管理程序 (VMM) 的细微差别。例如, vmm/scripts/kernel/cloud_hypervisor/build.sh 专门用于在 x86-64 上为 Cloud Hypervisor 构建 vmlinux.bin ,而 vmm/scripts/kernel/qemu/build.sh 则专注于为 QEMU 生成 bzImage ,并启用 BLK_DEV_INITRD 和 VIRTIO 驱动程序等关键选项。类似地, vmm/scripts/kernel/stratovirt/build.sh 构建专为 openEuler 和 StratoVirt 定制的 aarch64 vmlinux.bin 镜像。

“附加”定制方法的设计选择确保仅包含对 Kuasar VMM 沙箱至关重要的功能,从而缩小攻击面,增强安全态势,并提升性能。有关该方法和性能影响的更多详细信息,请参阅 vmm/scripts/kernel/build-kernel/how-to-tailor-linux-kernel-for-kuasar-security-container.md 。

VMM 任务生命周期和运行时管理

vmm-task 组件负责协调客户虚拟机 (VM) 环境中容器和进程的生命周期。它在客户虚拟机内部以进程 ID 1 运行,管理初始化、资源分配、网络和异步 I/O。该系统利用 ttrpc 进行进程间通信,并利用 tokio 实现并发,从而能够高效地管理容器工作负载。

vmm-task 服务的主要入口点位于 vmm/task/src/main.rs 。该组件初始化虚拟机环境,设置必要的文件系统和内核参数。它还配置一个 ttrpc 服务器,以公开用于管理任务、沙箱和流式传输的服务,从而允许外部组件与虚拟机的内部进程交互。vmm vmm-task 还处理操作系统信号,包括回收子进程和管理优雅关机。

vmm-task 的配置参数由 vmm/task/src/config.rs 中的 TaskConfig 结构管理。该配置通过解析 /proc/cmdline 中的内核命令行参数动态确定,从而允许在运行时进行灵活调整,而无需依赖外部配置文件。

vmm-task 中的容器和进程管理由 shim 层负责,该层在 vmm/task/src/container.rs 中实现。此层充当 containerd 和符合 OCI 标准的运行时(例如 runc 之间的中介。它负责创建容器、解析 OCI Spec 、设置存储以及管理 stdio 重定向。该组件区分初始容器进程和后续 exec 进程,从而提供不同的生命周期管理。一个值得注意的设计是 ShimExecutor ,这是一个自定义的 spawner,它与 containerd-shim 监控系统集成,可以精确地跟踪进程生命周期。错误报告机制完善,可以从 runc 日志文件中提取详细信息。vmm vmm-task 还与 SandboxResources 集成,以管理容器存储生命周期。

沙箱的资源管理集中在 vmm/task/src/sandbox.rs 中的 SandboxResources 内。该组件负责管理存储卷,包括添加、延迟和垃圾回收。它与 vmm/task/src/device.rs 中的 DeviceMonitor 交互 DeviceMonitor 以跟踪和管理块设备和 SCSI 设备。DeviceMonitor 监听内核 uevent,并允许其他组件订阅设备相关事件,从而确保系统能够感知可用硬件。此外, vmm/task/src/sandbox.rs 还负责设置 Linux 命名空间(IPC、UTS、PID)并配置 sysctl 参数以维护沙箱的隔离性。vmm vmm/task/src/mount.rs 中的 get_cgroup_mounts 函数生成必要的 cgroup 挂载配置,支持 v1 和 v2 层次结构。

网络配置由位于 vmm/task/src/netlink.rs Handle 结构处理。该组件提供了一个基于 rtnetlink 高级 API,用于管理客户虚拟机内的网络接口、IP 地址和路由表,通常供代理服务使用。这包括启用环回、更新接口、添加和删除 IP 地址以及管理路由等操作,所有这些操作都使用 protobuf 定义的结构,以实现无缝的 RPC 集成。

I/O 和流管理对于容器功能至关重要,并在 vmm/task/src/io.rs 文件中实现。该文件定义了 ProcessIO 及相关函数,用于管理容器进程的 stdin 、 stdout 和 stderr ,支持多种机制,例如 FIFO、控制台套接字、直接流和 vsock 。它还处理控制台连接,提供用于数据复制的异步函数,并包含一个符合 AsyncRead 和 AsyncWrite 特性的 vsock 流的 VsockIo 实现。vmm vmm/task/src/streaming.rs 中的 Streaming 服务通过 ttrpc 实现流功能,管理标准流的 I/O 通道。此外, vmm/task/src/debug.rs 提供了通过 VSOCK 建立调试控制台的功能,为虚拟机或容器提供 shell 接口。

TTRPC 协议和代码生成

Kuasar 虚拟机监控器 (VMM) 利用 ttrpc 进行进程间通信,而 ttrpc 依赖于从 protobuf 定义生成 Rust 代码。此代码生成过程由 vmm/common/build.rs 构建脚本管理,实现了不同 VMM 组件之间无缝的数据交换和远程过程调用。

vmm/common/build.rs 脚本利用 ttrpc-codegen crate 将 .proto 文件(例如 sandbox.proto 、 events.proto 和 fieldpath.proto )转换为 Rust 源代码。生成的代码为 ttrpc 协议提供了必要的客户端和服务端实现,确保类型安全且高效的通信。例如, vmm/common/src/api/mod.rs 中的 sandbox_ttrpc 和 streaming_ttrpc 模块分别提供了沙箱管理和数据流服务的特定 ttrpc 绑定。

为了维护代码质量并抑制自动生成文件中不必要的警告,构建脚本会进行一些生成后修改。它会移除 #![allow(box_pointers)] 代码检查,该检查用于解决与特定 Rust 特性的兼容性问题,并将 #![allow(clippy::all)] 插入到生成的 _ttrpc.rs 文件中。这确保了自动生成的代码中可能出现的 clippy 警告被抑制,从而保持代码库的整洁,使其专注于开发者编写的逻辑。这使得项目能够专注于生成的 API 组件的语义正确性,而不会被那些并非由开发者直接维护的代码的风格检查所分散注意力。

使用过程宏推导命令行参数

Kuasar 利用过程宏从 Rust 结构体生成命令行参数,简化了定义和解析各种组件参数的过程。这种方法支持两种主要的生成方式:创建结构化的 Param 对象和生成原始命令行参数字符串。这些宏定义在 vmm/sandbox/derive/src/lib.rs 文件中。

CmdLineParams 宏为 crate::param::ToParams trait 生成一个实现,产生一个 crate::param::Param 对象向量。每个 Param 对象代表一个结构化参数,包含一个名称和一个 Property 对象列表。这使得命令行参数能够以详细且有序的方式表示,其中参数中的每个属性都可以具有特定的配置,例如 param 、 key 、 predicate 、 generator 、 ignore_key 和 ignore 属性。这些属性支持对属性生成进行动态控制,允许基于 Rust 表达式有条件地包含或转换值。

相反, CmdLineParamSet 宏会为 crate::param::ToCmdLineParams trait 生成一个实现,该实现会输出一个表示原始命令行参数的 String 向量。此宏处理结构体字段,并使用带有 key 和 ignore 子属性的 param 属性来自定义命令行键或排除字段。它按类型(例如布尔值、原始类型、 Vec 或 Option )对字段进行分类,并将参数生成委托给专门的 crate::param 类型。这种方法通过抽象将 Rust 数据结构转换为可执行参数的过程,简化了命令行接口的创建。

这两个宏 convert_case 利用 syn 和 quote crate 来解析 Rust 语法树和生成新的 Rust 代码。convert_case crate 用于将标识符转换为 kebab-case 格式,以确保生成的命令行参数格式一致。