前言

Kuasar 是一款支持多种类型沙箱统一管理的容器运行时,可同时支持业界主流的多种沙箱隔离技术,例如包括基于内核的原生容器沙箱、基于轻量级虚拟化技术的 microVM 沙箱、基于进程级虚拟化的 App Kernel 沙箱,以及新兴的 WebAssembly 沙箱。

目前 Kuasar 仍处于积极开发的过程中,但是 GitHub release 上的最新发布停留在 2024 年 8 月 19 日的 v1.0.0 版本,想要使用最新的版本需要自行编译,笔者在此过程中发现 Kuasar 的编译构建比较繁琐,涉及多种编程语言工具链以及复杂的传递依赖关系,于是整理详细过程形成本文,以供读者参考。

[!NOTE]

  1. 为了避免权限问题,本文所有操作均以 root 身份执行;
  2. 本文所用代码版本为 Commit 54d5d2e,此后上游依赖仓库发生了较大变动,本文中部分操作可能已不再适用。

准备工作

安装 cargo

安装 Cargo 的最简单方法是按照 Rust 官网教程执行以下命令:

curl https://sh.rustup.rs -sSf | sh

安装构建工具

运行以下命令安装构建工具:

apt install build-essential

安装其他工具:

apt install clang cmake unzip flex bison

安装沙箱环境

安装 Cloud Hypervisor

直接下载预编译的二进制文件进行安装:

curl -L -O https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/v43.0/cloud-hypervisor
chmod +x cloud-hypervisor
mv cloud-hypervisor /usr/local/bin

安装 Quark

安装依赖

Quark 是使用 Rust 语言开发的,构建之前需要安装 Rust nightly 版本,目前能正常构建 Quark 的最新 nightly 版本是 nightly-2023-12-11-x86_64-unknown-linux-gnu

rustup toolchain install nightly-2023-12-11-x86_64-unknown-linux-gnu
rustup default nightly-2023-12-11-x86_64-unknown-linux-gnu

然后将 rust-src 组件添加到当前工具链中:

rustup component add rust-src

接着安装 cargo-xbuild 以进行 qkernel 交叉编译:

cargo install cargo-xbuild

最后,安装 libcap 库:

apt-get install libcap-dev

此外,还需要安装一些额外的库来编译 RDMA 模块:

apt-get install build-essential cmake gcc libudev-dev libnl-3-dev \
libnl-route-3-dev ninja-build pkg-config valgrind python3-dev cython3 \
python3-docutils pandoc libclang-dev

如有需要,可以根据 Quark 文档 的说明安装编译 GPU 模块所需要的依赖,笔者这里不再赘述。

编译安装

首先获取 Quark 源代码:

git clone [email protected]:QuarkContainer/Quark.git

然后运行以下命令编译安装:

cd Quark
make
make install

配置运行

创建日志文件夹:

mkdir /var/log/quark

修改配置文件 /etc/quark/config.json,将 Sandboxed 选项设置为 true

{
  "DebugLevel"    : "Error",
  "KernelMemSize" : 24,
  "LogType"       : "Sync",
  "LogLevel"      : "Simple",
  "UringIO"       : true,
  "UringBuf"      : true,
  "UringFixedFile": false,
  "EnableAIO"     : true,
  "PrintException": false,
  "KernelPagetable": false,
  "PerfDebug"     : false,
  "UringStatx"    : false,
  "FileBufWrite"  : true,
  "MmapRead"      : false,
  "AsyncAccept"   : true,
  "EnableRDMA"    : false,
  "RDMAPort"      : 1,
  "PerSandboxLog" : false,
  "ReserveCpuCount": 1,
  "ShimMode"      : false,
  "EnableInotify" : true,
  "ReaddirCache"  : true,
  "HiberODirect"  : true,
  "DisableCgroup" : true,
  "CopyDataWithPf": true,
  "TlbShootdownWait": true,
  "Sandboxed": true
}

[!NOTE]

确保配置文件中的 ShimMode 选项为 false,并且 Sandboxed 选项为 true。

安装 WasmEdge

根据 WasmEdge 文档 说明执行安装指令:

VERSION=0.13.5
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- -v $VERSION

[!NOTE]

WasmEdge 要求其 C 库 (WasmEdge lib) 和 Rust SDK (wasmedge-sdk) 的版本严格对应,目前 kuasar WASM 运行时使用的 wasmedge-sdk 版本为 0.13.2,根据 wasmedge-sdk 文档 WasmEdge C 库对应的版本为 0.13.5

安装 containerd

Kuasar 官方文档中建议安装他们维护的 containerd 以获得完整的功能体验,该版本在官方的 1.7.0 之上进行了一些定制化修改。

安装依赖

从源代码编译安装 containerd 需要 Go 语言环境,首先从官网下载预编译的二进制文件压缩包:

curl -L -O https://golang.google.cn/dl/go1.23.4.linux-amd64.tar.gz

然后使用以下命令解压:

rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz

然后在 $HOME/.profile 中添加环境变量:

echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
source ~/.profile

最后验证一下是否安装成功:

4f943d312366109d3c053e6d1dfa409d.png

编译安装

将源代码克隆至本地:

git clone -b v0.2.0-kuasar https://github.com/kuasar-io/containerd.git

运行以下命令完成编译安装:

cd containerd
make
make install

安装 CNI 插件:

curl -L https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz -o cni-plugins.tgz
mkdir -p /opt/cni/bin
tar -xvzf cni-plugins.tgz -C /opt/cni/bin

安装 runc:

apt-get install runc

配置运行

运行以下命令自动生成默认配置,如果提示目录或文件不存在的话需要手动创建:

containerd config default > /etc/containerd/config.toml

默认配置文件中需要增加 kuasar 所用运行时的有关配置,具体如下:

  • vmm
[proxy_plugins.vmm]
  type = "sandbox"
  address = "/run/vmm-sandboxer.sock"
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.kuasar-vmm]
  runtime_type = "io.containerd.kuasar-vmm.v1"
  sandboxer = "vmm"
  io_type = "streaming"
  • Quark
[proxy_plugins.quark]
  type = "sandbox"
  address = "/run/quark-sandboxer.sock"
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.kuasar-quark]
  runtime_type = "io.containerd.kuasar-quark.v1"
  sandboxer = "quark"
  • wasm
[proxy_plugins.wasm]
  type = "sandbox"
  address = "/run/wasm-sandboxer.sock"
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.kuasar-wasm]
  runtime_type = "io.containerd.kuasar-wasm.v1"
  sandboxer = "wasm"

[!IMPORTANT]

AppArmor 特性尚未支持,记得在配置文件中更新 disable_apparmor = true 条目!

最后,启动 containerd:

ENABLE_CRI_SANDBOXES=1 containerd

<summary>报错解决</summary>
<p>如果 containerd 启动时出现以下报错:</p>
<img src=":/f1198165459e408ab1c563a1eec4bc5f" alt="8f1672eb769d91670bbe2af69cd80940.png" style="zoom:80%;" />
<p>安装 nerdctl 后以默认配置运行任一测试容器即可消除该错误。</p>

安装 crictl

crictl 是一个用于与兼容 CRI 的容器运行时交互的命令行工具,根据官方文档安装即可:

VERSION="v1.32.0" # check latest version in releases page
curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz
tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz

导入配置文件:

cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
pull-image-on-create: false
EOF

安装 virtiofsd

virtiofsd 是一个用于虚拟机和主机之间共享文件系统的守护进程,可以直接从官网下载预编译的二进制文件:

curl -L "https://gitlab.com/virtio-fs/virtiofsd/-/jobs/artifacts/main/download?job=publish" -o virtiofsd.zip

使用以下命令解压安装:

unzip virtiofsd.zip
mv target/x86_64-unknown-linux-musl/release/virtiofsd /usr/local/bin

编译源码

将源码克隆至本地:

git clone https://github.com/kuasar-io/kuasar.git

编译安装:

cd kuasar
make all
make install

[!NOTE]

Guest OS 镜像需在容器里编译,所以需要提前启动 containerd 或其他容器运行时。

笔者在编译客户机镜像时还遇到了如下的报错:

53b37ee69b4d22751c730e52e69bc119.png

kuasar/vmm/scripts/image/build.sh 脚本中 # build rootfs in container 部分的 bash 替换为 /bin/bash 即可。

<summary>其他报错</summary>
<p>笔者最初在 WSL 中编译时还出现了如下报错:</p>
<img src="https://img.jjl9807.com/i/2025/03/13/67d27ad3e2181.png" alt="9730a18bda7a2ff7fbd41613e7a2b657.png" style="zoom:50%;"/>
<p>经过反复尝试后最终通过转战 VMware 虚拟机解决。</p>

运行与测试

启动 kuasar

使用以下命令启动 kuasar:

  • vmm
nohup vmm-sandboxer --listen /run/vmm-sandboxer.sock --dir /run/kuasar-vmm &
  • quark
nohup quark-sandboxer --listen /run/quark-sandboxer.sock --dir /var/lib/kuasar-quark &
  • wasm
nohup wasm-sandboxer --listen /run/wasm-sandboxer.sock --dir /run/kuasar-wasm &

运行测试容器

由于 Kuasar 属于低阶容器运行时,所有交互都应通过 containerd 中的 CRI 完成,例如 crictl 或 Kubernetes,这里笔者用的是上文已经安装过的 crictl。

Kuasar 仓库已经提供了启动测试容器的脚本,直接运行即可:

# For vmm, quark or runc
# NOTE: The '<runtime>` option should be kuasar-vmm, kuasar-quark or kuasar-runc.
./examples/run_example_container.sh <runtime>

# For wasm
# NOTE: Wasm container needs its own container image so the script has to build and import the container image at first.
./examples/run_example_wasm_container.sh

参考资料