containers/libkrun
GitHub: containers/libkrun
libkrun 是一个基于 KVM/HVF 的轻量级虚拟化库,为进程提供隔离能力并抽象底层虚拟化细节。
Stars: 2004 | Forks: 166
# libkrun
```libkrun``` 是一个动态库,允许程序在使用 Linux 上的 [KVM](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt) 虚拟化和 macOS/ARM64 上的 [HVF](https://developer.apple.com/documentation/hypervisor) 虚拟化时,轻松获得在部分隔离环境中运行进程的能力。
它将一个 VMM(虚拟机监视器,即 Hypervisor 的用户态部分)与实现其目的所需的最少模拟设备集成,抽象了虚拟机管理的大部分复杂性,提供了一个简单的 C API。
## 使用场景
* [crun](https://github.com/containers/crun/blob/main/krun.1.md):为容器和机密工作负载添加基于虚拟化的隔离。
* [krunkit](https://github.com/containers/krunkit):在 macOS 上运行启用 GPU(通过 [venus](https://docs.mesa3d.org/drivers/venus.html))的轻量级虚拟机。
* [muvm](https://github.com/AsahiLinux/muvm):通过 [native context](https://www.youtube.com/watch?v=9sFP_yddLLQ) 启用 GPU 加速来启动微虚拟机,以运行需要 4k 页的游戏。
## 目标与非目标
### 目标
* 使其他项目能够轻松获得基于 KVM 的进程隔离能力。
* 自给自足(无需调用外部 VMM)且易于使用。
* 尽可能精简,仅实现实现目标所需的功能。
* 在各方面(内存占用、CPU 使用率和启动时间)尽可能减少足迹。
* 与合理数量的工作负载兼容。
### 非目标
* 成为一个通用的 VMM。
* 与所有种类的工作负载兼容。
## 变体
本项目提供以下库变体:
- **libkrun**:适用于所有支持虚拟化的系统的通用变体。
- **libkrun-sev**:包含对 AMD SEV(SEV、SEV-ES 和 SEV-SNP)内存加密和远程认证的变体。需要支持 SEV 的 CPU。
- **libkrun-tdx**:包含对 Intel TDX 内存加密的变体。需要支持 TDX 的 CPU。
- **libkrun-efi**:捆绑 OVMF/EDK2 以引导发行版提供的内核的变体(仅适用于 macOS)。
每个变体都会生成具有不同名称(和 ```soname```)的动态库,因此可以在同一系统中同时安装。
## 虚拟设备支持
### 所有变体
* virtio-console
* virtio-block
* virtio-fs
* virtio-gpu(venus 和 native-context)
* virtio-net
* virtio-vsock(用于 TSI 和套接字重定向)
* virtio-balloon(仅免费页报告)
* virtio-rng
* virtio-snd
## 网络
在 ```libkrun``` 中,网络由两种互斥的技术提供:**virtio-vsock + TSI** 和 **virtio-net + passt/gvproxy**。
### virtio-vsock + TSI
这是一种称为 **Transparent Socket Impersonation** 的新技术,允许虚拟机无需虚拟接口即可获得网络连接能力。该技术支持传出和传入连接。运行在虚拟机中的用户态应用程序可以透明地连接到虚拟机外部的端点,并接收来自外部的连接到虚拟机内部监听的端口。
#### 启用 TSI
当未向虚拟机添加网络接口时,AF_INET 和 AF_INET6 的 TSI 会自动启用。此外,如果使用了 `krun_set_root` 将 `/` 设置为根文件系统,则 AF_UNIX 的 TSI 也会启用。
#### 已知限制
- 需要一个自定义内核(例如 **libkrunfw** 中捆绑的内核)。
- 仅限于 SOCK_DGRAM 和 SOCK_STREAM 套接字,以及 AF_INET、AF_INET6 和 AF_UNIX 地址族(例如,不支持原始套接字)。
- 不支持从客户机监听 SOCK_DGRAM 套接字。
- 当 AF_UNIX 套接字启用 TSI 时,仅支持绝对路径作为地址。
### **virtio-net + passt/gvproxy**
一种传统的虚拟接口,允许客户机通过 VMM 使用 [passt](https://passt.top/passt/about/) 或 [gvproxy](https://github.com/containers/gvisor-tap-vsock) 等支持应用程序与外界通信。
#### 启用 virtio-net
使用 `krun_add_net_unixstream` 和/或 `krun_add_net_unixdgram` 添加连接到用户态网络代理的 virtio-net 接口。
## 安全模型
libkrun 的安全模型主要基于以下考虑:客户机与 VMM 属于相同的安全上下文。对于许多操作,VMM 作为主机上客户机的代理。主机上 VMM 可访问的资源,潜在上也可被客户机通过它访问。
在定义环境的安全实现时,应将客户机和 VMM 视为单一实体。为防止客户机访问主机资源,需要使用主机的操作系统安全功能在隔离环境中运行 VMM。在 Linux 上,用于此目的的主要机制是命名空间。单用户系统可能采用更宽松的安全策略,仅需确保 VMM 以特定的 UID/GID 运行。
虽然大多数 virtio 设备允许客户机访问主机资源,但其中两个设备在使用时需要特别注意:virtio-fs 和 virtio-vsock+TSI。
### virtio-fs
当通过 virtio-fs 设备使用 `krun_set_root` 和/或 `krun_add_virtiofs` 将主机文件系统中的目录暴露给客户机时,libkrun **不**提供任何防护,防止客户机访问同一文件系统中的其他目录,甚至其他文件系统。
应结合使用来自主机的挂载点隔离机制与 virtio-fs。
此外,使用 virtio-fs 时,客户机可能会耗尽文件系统资源(如 inode 限制和磁盘容量)。应在主机上实施控制以缓解此问题。
### virtio-vsock + TSI
当启用 TSI 时,VMM 作为 AF_INET、AF_INET6 和 AF_UNIX 套接字的代理,处理传入和传出连接。就此而言,应将 VMM 和客户机视为在网络上下文中运行。因此,应对 VMM 应用与对客户机相同的限制。
## 构建与安装
### Linux(通用变体)
#### 要求
* [libkrunfw](https://github.com/containers/libkrunfw)
* 一个可用的 [Rust](https://www.rust-lang.org/) 工具链
* C 库静态库,因为 [init](init/init.c) 二进制文件是静态链接的(Fedora 中的包为 ```glibc-static```)
* patchelf
#### 可选特性
* **GPU=1**:启用 virtio-gpu。需要 virglrenderer-devel。
* **VIRGL_RESOURCE_MAP2=1**:使用 virgl_resource_map2 函数。需要已打补丁的 virglrenderer-devel(包含 [1374](https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1374))。
* **BLK=1**:启用 virtio-block。
* **NET=1**:启用 virtio-net。
* **SND=1**:启用 virtio-snd。
#### 编译
```
make [FEATURE_OPTIONS]
```
#### 安装
```
sudo make [FEATURE_OPTIONS] install
```
### Linux(SEV 变体)
#### 要求
* [libkrunfw](https://github.com/containers/libkrunfw) 的 SEV 变体,提供 ```libkrunfw-sev.so``` 库。
* 一个可用的 [Rust](https://www.rust-lang.org/) 工具链
* C 库静态库,因为 [init](init/init.c) 二进制文件是静态链接的(Fedora 中的包为 ```glibc-static```)
* patchelf
* OpenSSL 头文件和库(Fedora 中的包为 ```openssl-devel```)
#### 编译
```
make SEV=1
```
#### 安装
```
sudo make SEV=1 install
```
### Linux(TDX 变体)
#### 要求
* [libkrunfw](https://github.com/containers/libkrunfw) 的 TDX 变体,提供 ```libkrunfw-tdx.so``` 库。
* 一个可用的 [Rust](https://www.rust-lang.org/) 工具链
* C 库静态库,因为 [init](init/init.c) 二进制文件是静态链接的(Fedora 中的包为 ```glibc-static```)
* patchelf
* OpenSSL 头文件和库(Fedora 中的包为 ```openssl-devel```)
#### 编译
```
make TDX=1
```
#### 安装
```
sudo make TDX=1 install
```
#### 限制
TDX 版本的 libkrun 仅支持 1 个 vCPU 且内存小于或等于 3072 MiB 的客户机。
### macOS(EFI 变体)
#### 要求
* 一个可用的 [Rusthttps://www.rust-lang.org/) 工具链
* 运行 macOS 14 或更高版本的主机
#### 编译
```
make EFI=1
```
#### 安装
```
sudo make EFI=1 install
```
### macOS(通用变体)
#### 要求
* 一个可用的 [Rust](https://www.rust-lang.org/) 工具链
* 运行 macOS 14 或更高版本的主机
* Homebrew 包 `lld` 和 `xz`
#### 编译
```
make [FEATURE_OPTIONS]
```
[init](init/init.c) 二进制文件使用 clang 和 lld 进行交叉编译。
会自动从 Debian 仓库生成合适的 sysroot。
#### 安装
```
sudo make [FEATURE_OPTIONS] install
```
## 使用该库
尽管是用 Rust 编写,但此库提供了一个简单的 C API,定义在 [include/libkrun.h](include/libkrun.h)。
## 示例
### chroot_vm
这是一个提供类似 `chroot` 功能的简单示例,使用 `libkrun`。
#### 构建 chroot_vm
要能够运行 `chroot_vm`,需要构建启用了 `virtio-block` 和 `virtio-net` 可选特性的 libkrun:
```
make BLK=1 NET=1
sudo make BLK=1 NET=1 install
cd examples
make
```
#### 运行 chroot_vm
要能够运行 `chroot_vm`,首先需要一个目录作为隔离程序运行的根文件系统。
使用 `rootfs` 目标从 Fedora 容器镜像中获取准备好的根文件系统(注意:必须安装 [podman](https://podman.io/)):
```
make rootfs
```
现在可以使用 `chroot_vm` 在新的根文件系统中运行进程:
```
./chroot_vm ./rootfs_fedora /bin/sh
```
如果未将 `libkrun` 和/或 `libkrunfw` 库安装到 `ld.so.conf` 配置中包含的路径,可能会出现如下错误:
```
./chroot_vm: error while loading shared libraries: libkrun.so: cannot open shared object file: No such file or directory
```
为避免此问题,请使用 `LD_LIBRARY_PATH` 环境变量指向库的安装位置。例如,如果库安装在 `/usr/local/lib64`,可以使用如下命令:
```
LD_LIBRARY_PATH=/usr/local/lib64 ./chroot_vm rootfs_fedora/ /bin/sh
```
## 状态
```libkrun``` 已达到成熟阶段,从版本 ```1.0.0``` 开始,公共 API 保证稳定,遵循 [SemVer](https://semver.org/)。
## 联系方式
主要的沟通渠道是 [libkrun Matrix 频道](https://matrix.to/#/#libkrun:matrix.org)。
## 感谢
```libkrun``` 整合了来自 [Firecracker](https://github.com/firecracker-microvm/firecracker)、[rust-vmm](https://github.com/rust-vmm/) 和 [Cloud-Hypervisor](https://github.com/cloud-hypervisor/) 的代码。
标签:C API, crun, HVF, krunkit, KVM, Linux虚拟化, macOS虚拟化, muvm, 动态库, 可视化界面, 容器隔离, 最小化依赖, 机密计算, 用户态虚拟机, 虚拟化, 虚拟化监控器, 虚拟化隔离, 轻量级VMM, 运行时隔离, 进程隔离, 通知系统