目前,虚拟化容器技术的应用,大致可以分为三类:虚拟机、系统容器和应用容器。
他们之间的区别主要是,虚拟机运行的是一个完整的操作系统,包括内核和用户空间工具等等,而容器是通过 Linux Namespaces 和 Cgroups 等技术运行的一套隔离环境,容器和宿主机共享同一个操作系统内核。应用容器主要针对特定任务,容器的创建和销毁一般根据任务调度而定,当任务结束时,容器也会停止运行。系统容器则更像是轻量虚拟机,容器的运行和结束与特定任务无关,由用户自行决定开启和结束。更详细的区别对比参见:About containers and VMs - Incus documentation
我们熟知的 Docker 就是应用容器的典型代表。而本文的 Incus 则支持虚拟机和系统容器。
快速开始
按照官网文档说明 How to install Incus - Incus documentation 安装并初始化 Incus。
incus remote list
展示了 Incus 的 Image 下载源,例如:
➜ incus remote list
+-----------------+-----------------------------------------+---------------+-------------+--------+--------+--------+
| NAME | URL | PROTOCOL | AUTH TYPE | PUBLIC | STATIC | GLOBAL |
+-----------------+-----------------------------------------+---------------+-------------+--------+--------+--------+
| images | https://images.linuxcontainers.org | simplestreams | none | YES | NO | NO |
+-----------------+-----------------------------------------+---------------+-------------+--------+--------+--------+
| local (current) | unix:// | incus | file access | NO | YES | NO |
+-----------------+-----------------------------------------+---------------+-------------+--------+--------+--------+
| mirror | https://mirrors.bfsu.edu.cn/lxc-images/ | simplestreams | none | YES | NO | NO |
+-----------------+-----------------------------------------+---------------+-------------+--------+--------+--------+
对于国内大陆用户,可以考虑添加国内 Image 源:
incus remote add mirror https://mirrors.bfsu.edu.cn/lxc-images/ --protocol=simplestreams --public
更多的国内源,参见:LXC Images 软件仓库镜像使用帮助 - MirrorZ Help
通过 incus image list mirror:debian
列出 mirror 源中名称包含 debian 的 Image.
通过指定 Image 和 Instance 名称,我们就可以创建一个系统容器:
incus create <image> <instance> # create an instance based on image
# or
incus launch <image> <instance> # create and start an instance
例如 incus launch mirror:debian/12 debian12
即可创建并启动一个名为 debian12
的 Debian 12 (Bookworm) 容器。
接着,incus exec debian12 -- bash
即可进入容器交互。
挂载目录
Incus 的目录挂载是通过添加 Device 的方式,通过添加一个 disk
类型的 Device,就可以将宿主机上的目录挂载到容器内。而且,这种方式是可热插拔的!这就意味着,在已经创建容器后,我们依然可以随时挂载或卸载目录,是不是和 Docker 的 Volume Mapping 很不一样呢!这简直太酷了!
例如,通过下面的命令,我们创建了一个名叫 data
的 disk
类型的 Device, 可以将宿主机上的 /src
目录挂载到容器 debian12
上的 /data
目录。
incus config device add debian12 data disk source=/src path=/data
通过 incus config device remove debian12 data
即可将其移除。
端口映射
同样地,Device 还有很多种类型和用法,其中就包括 proxy
类型。这种类型的 Device 可以实现宿主机和容器间的网络转发。
例如,通过下面的命令,创建一个名为 ssh
的 Device(名字随便起啦),将发往宿主机的 127.0.0.1:2201
的 TCP 流量转发到容器 debian12
内的 127.0.0.1:22
端口的。这样,便可以通过 SSH 访问容器来进行开发。
incus config device add debian12 ssh proxy listen=tcp:127.0.0.1:2201 connect=tcp:127.0.0.1:22
NVIDIA 显卡支持(WSL2)
由于我的 Incus 环境位于 WSL2 中,所以这里只实践测试了 WSL2 上的 Incus 容器的 NVIDIA 显卡支持,其他 Linux 环境请参见:Type: gpu - Incus documentation 以及 Instance options - Incus documentation
一般来说,在 Windows 上安装最新的 NVIDIA 显卡驱动,并将 WSL2 的内核更新到最新版,就完成了 WSL2 的 NVIDIA 显卡配置,此时,在 WSL2 中执行 nvidia-smi
即可看到显卡信息。
为容器启用 NVIDIA 显卡支持,需要安装 NVIDIA Container Toolkit,安装方式参见:Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.14.4 documentation
- 对于配置了 ArchLinuxCN 的 ArchLinux:
pacman -S nvidia-container-toolkit
- 对于配置了 AUR 的 ArchLinux:
paru -S aur/nvidia-container-toolkit
WSL2 在启动时,会自动只读挂载 /usr/lib/wsl/lib
目录和 /usr/lib/wsl/drivers
目录,前者包含一些 NVIDIA 的运行时库和 CUDA 库,源目录位于 C:\Windows\System32\lxss\lib
。后者包含各种设备的驱动文件,源目录位于 C:\Windows\System32\DriverStore\FileRepository
,当然,NVIDIA 显卡驱动也在其中。
为了让 Incus 创建的容器拥有 NVIDIA 显卡支持,我们模仿 WSL2 配置 NVIDIA 环境的方式,只需将宿主机上的 /usr/lib/wsl
目录也挂载到容器中,并配置容器内的链接库查找路径,最后为容器启用 nvidia.runtime
选项即可。
示例代码如下:
incus create <image> <instance>
incus config device add <instance> libwsl disk source=/usr/lib/wsl path=/usr/lib/wsl recursive=true
incus config set <instance> nvidia.runtime="true"
incus file push /etc/ld.so.conf.d/ld.wsl.conf <instance>/etc/ld.so.conf.d/ld.wsl.conf
incus start <instance>
incus exec <instance> -- nvidia-smi
方便起见,我们可以将这套配置保存为一个 Profile 来供日后使用。创建一个名为 nv
的 Profile:
incus profile create nv
incus profile edit nv
并填入以下内容:
config:
nvidia.driver.capabilities: all
nvidia.runtime: "true"
description: NVIDIA Support
devices:
eth0:
name: eth0
network: incusbr0
type: nic
ldconfig:
path: /etc/ld.so.conf.d/ld.wsl.conf
readonly: "true"
required: "true"
source: /etc/ld.so.conf.d/ld.wsl.conf
type: disk
libwsl:
path: /usr/lib/wsl
recursive: "true"
required: "true"
source: /usr/lib/wsl
type: disk
root:
path: /
pool: default
type: disk
name: nv
used_by: []
这样的话,以后创建需要 NVIDAI 显卡支持的容器时,只需指定这个 Profile 即可:
incus launch <image> <instance> -p nv