LXD
LXD 是 Canonical 针对容器(通过 LXC)和虚拟机(通过 QEMU)的管理器/虚拟机监控器。
安装
或者,您可以直接启用/启动 lxd.service
,以防您希望实例自动启动等。
配置
非特权容器
建议使用非特权容器(有关差异的解释,请参阅Linux 容器#特权或非特权容器)。
为此,请修改 /etc/subuid
和 /etc/subgid
(如果这些文件不存在,请创建它们),以包含每个能够运行容器的用户的容器化 uid/gid 对的映射。以下示例仅适用于 root 用户(和 systemd 系统单元)
# usermod -v 1000000-1000999999 -w 1000000-1000999999 root
现在,默认情况下,每个容器都将以 unprivileged
方式启动。
有关替代方法,请参阅#特权容器。
配置 LXD
首次启动时,需要配置 LXD。
以 root 身份运行
# lxd init
这将启动终端中的交互式配置指南,其中涵盖了存储、网络等不同主题。
您可以在官方入门指南中找到概述。
以非特权用户身份访问 LXD
默认情况下,LXD 守护进程允许 lxd
组中的用户访问,因此将您的用户添加到此组。
用法
LXD 由两部分组成
- 守护进程(lxd 二进制文件)
- 客户端(lxc 二进制文件)
客户端用于控制一个或多个守护进程。
客户端也可以用于控制远程 LXD 服务器。
命令概览
您可以通过输入以下内容获取所有可用命令的概览
$ lxc
创建容器
您可以使用 lxc launch
创建容器,例如
$ lxc launch ubuntu:20.04
容器基于镜像,这些镜像从镜像服务器或远程 LXD 服务器下载。
您可以使用以下命令查看已添加服务器的列表
$ lxc remote list
您可以使用 lxc image list
列出服务器上的所有镜像,例如
$ lxc image list images:
这将显示默认服务器之一上的所有镜像:images.linuxcontainers.org
您还可以通过添加发行版名称等术语来搜索镜像
$ lxc image list images:debian
使用来自特定服务器的镜像启动容器,使用
$ lxc launch servername:imagename
例如
$ lxc launch images:centos/8/amd64 centos
要创建 amd64 Arch 容器
$ lxc launch images:archlinux/current/amd64 arch
创建虚拟机
只需将标志 --vm
添加到 lxc launch
$ lxc launch ubuntu:20.04 --vm
- 目前,虚拟机支持的功能比容器少(例如,有关详细信息,请参阅关于虚拟机的详细信息)。
- 只有官方镜像的
cloud
变体默认启用 lxd-agent(这是lxc exec
等常用 lxc 命令所必需的)。
您可以使用lxc image list images: cloud
或lxc image list images: distribution-name cloud
搜索云镜像。
如果您使用其他镜像或遇到问题,请查看#虚拟机内的 lxd-agent。
使用和管理容器或虚拟机
容器/虚拟机配置
您可以向实例(容器和虚拟机)添加各种选项。
有关详细信息,请参阅LXD 官方高级指南中的实例配置。
技巧和窍门
在主机上通过名称访问容器
这假设您正在使用名为 lxdbr0
的默认桥接,并且您正在使用 systemd-resolved。
# systemd-resolve --interface lxdbr0 --set-domain '~lxd' --set-dns $(lxc network get lxdbr0 ipv4.address | cut -d / -f 1)
现在您可以通过名称访问容器
$ ping containername.lxd
其他解决方案
似乎 systemd-resolve 解决方案在一段时间后停止工作。
另一种解决方案是将 systemd-networkd 与以下 lxd.network
一起使用(替换 x
和 y
以匹配您的桥接 IP)
/etc/systemd/network/lxd.network
[Match] Name=lxdbr0 [Network] DNS=10.x.y.1 Domains=~lxd IgnoreCarrierLoss=yes [Address] Address=10.x.y.1/24 Gateway=10.x.y.1
使用 Wayland 和 Xorg 应用程序
在容器内使用 GUI 应用程序有多种方法,您可以在官方 LXD 论坛中找到概述。
以下方法授予容器访问主机 Wayland (+Xwayland) 或 Xorg 套接字的权限。
将以下设备添加到容器配置文件
另请参阅有关设备的 LXD 文档。
GPU 的通用设备
mygpu: type: gpu
Wayland 套接字的设备
- 相应地调整显示 (wayland-0)。
- 如果
/mnt
和/tmp
中的目录尚不存在,请在容器内添加它们。
Waylandsocket: bind: container connect: unix:/run/user/1000/wayland-0 listen: unix:/mnt/wayland1/wayland-0 uid: "1000" gid: "1000" security.gid: "1000" security.uid: "1000" mode: "0777" type: proxy
Xorg(或 Xwayland)套接字的设备
Xsocket: bind: container connect: unix:/tmp/.X11-unix/X0 listen: unix:/mnt/xorg1/X0 uid: "1000" gid: "1000" security.gid: "1000" security.uid: "1000" mode: "0777" type: proxy
将套接字链接到容器内的正确位置
链接 Wayland 套接字的 Shell 脚本
#!/bin/sh mkdir /run/user/1000 ln -s /mnt/wayland1/wayland-0 /run/user/1000/wayland-0
链接 Xorg(或 Xwayland)套接字
#!/bin/sh ln -s /mnt/xorg1/X0 /tmp/.X11-unix/X0
将环境变量添加到容器内用户的配置
对于 Wayland
$ echo "export XDG_RUNTIME_DIR=/run/user/1000" >> ~/.profile $ echo "export WAYLAND_DISPLAY=wayland-0" >> ~/.profile $ echo "export QT_QPA_PLATFORM=wayland" >> ~/.profile
对于 Xorg(或 Xwayland)
$ echo "export DISPLAY=:0" >> ~/.profile
重新加载 ~/.profile
$ source ~/.profile
在容器中安装必要的软件
需要添加必要的软件。目前,您可以安装示例 GUI 应用程序;这可能会安装所有必要的软件包。
启动 GUI 应用程序
现在,您应该能够在容器内启动 GUI 应用程序(例如,通过终端),并使它们作为窗口出现在主机显示器上。
您可以尝试 glxgears 例如。
特权容器
- 特权容器未与主机隔离!
- 容器中的 root 用户是主机上的 root 用户。
- 尽可能使用非特权容器。
如果要设置特权容器,则必须提供配置键 security.privileged=true
。
在容器创建期间
$ lxc launch ubuntu:20.04 ubuntu -c security.privileged=true
或者对于已经存在的容器,您可以编辑配置
$ lxc config edit ubuntu
name: ubuntu profiles: - default config: ... security.privileged: "true" ...
添加磁盘设备
只读
如果要将磁盘设备从主机共享到容器,您只需向容器添加 disk
设备。虚拟 disk
设备需要一个名称(仅在 LXC 配置文件中内部使用)、主机文件系统上指向要挂载的磁盘的路径,以及容器文件系统上所需的挂载点。
$ lxc config device add containername virtualdiskname disk source=/path/to/host/disk/ path=/path/to/mountpoint/on/container
读写(非特权容器)
读/写访问的首选方法是使用 LXD 中包含的“shift”方法。
shift 基于 Linux 内核功能,并提供两个不同的版本
- 最新版本称为“idmapped mounts”,默认包含在所有上游内核 >5.12 中。因此,它也包含在常规 Arch Linux 内核 (linux) 中。
- 旧版本称为“shiftfs”,需要手动添加到大多数内核中作为内核模块。它作为遗留版本提供,以支持较旧的内核。您可以查看此 GitHub 仓库,该仓库使用来自 Ubuntu 内核的 shiftfs 内核模块:https://github.com/toby63/shiftfs-dkms
Shift 应该在安装了常规 Arch Linux 内核 (linux) 和 lxd 软件包的 Arch 系统上默认可用并激活。
1. 要检查您的系统上是否可用 shift,请运行 lxc info
输出的第一部分显示
kernel_features: idmapped_mounts: "true" shiftfs: "false"
如果 idmapped_mounts 或 shiftfs 为 true,则您的内核已包含它,您可以直接使用 shift。如果不是 true,您应该检查您的内核版本,并可能尝试上面提到的“shiftfs”遗留版本。
输出的第二部分显示
lxc_features: idmapped_mounts_v2: "true"
或
lxc_features: shiftfs: "true"
如果 idmapped_mounts 或 shiftfs 为 true,则 LXD 已启用它。如果未启用,您必须首先启用它。
2. 用法
然后,您可以简单地在磁盘设备选项中将“shift”配置键设置为“true”。请参阅:关于磁盘设备的 LXD 文档
另请参阅:LXD 论坛中的教程
Bash 补全不起作用
此解决方法可能会修复此问题
# ln -s /usr/share/bash-completion/completions/lxd /usr/share/bash-completion/completions/lxc
故障排除
虚拟机内的 lxd-agent
在某些虚拟机镜像中,默认情况下未启用 lxd-agent
。
在这种情况下,您必须手动启用它,例如通过挂载 9p
网络共享。这需要使用有效用户的控制台访问权限。
1. 使用 lxc console
登录,并相应地替换 virtualmachine-name
。
$ lxc console virtualmachine-name
以 root 身份登录
$ su root
挂载网络共享
$ mount -t 9p config /mnt/
进入文件夹并运行安装脚本(这将在虚拟机内启用 lxd-agent)
$ cd /mnt/ $ ./install.sh
成功安装后,使用以下命令重启
$ reboot
之后,lxd-agent
可用,lxc exec
应该可以工作。
检查内核配置
默认情况下,Arch Linux 内核已针对 Linux 容器及其前端 LXD 正确编译。但是,如果您使用的是自定义内核或更改了内核选项,则内核配置可能不正确。验证您的内核是否已正确配置
$ lxc-checkconfig
从容器内部查看时,资源限制未应用
lxd 将需要重启。启用 lxcfs.service
以便在启动时启动该服务。
启动虚拟机失败
如果您看到错误
Error: Couldn't find one of the required UEFI firmware files: [{code:OVMF_CODE.4MB.fd vars:OVMF_VARS.4MB.ms.fd} {code:OVMF_CODE.2MB.fd vars:OVMF_VARS.2MB.ms.fd} {code:OVMF_CODE.fd vars:OVMF_VARS.ms.fd} {code:OVMF_CODE.fd vars:qemu.nvram}]
这是因为 Arch Linux 不分发安全启动签名的 ovmf 固件。要启动虚拟机,您需要暂时禁用安全启动
$ lxc launch ubuntu:18.04 test-vm --vm -c security.secureboot=false
也可以通过执行以下操作将其添加到默认配置文件
$ lxc profile set default security.secureboot=false
systemd-networkd 没有 IPv4
从版本 244.1 开始,systemd 检测 /sys
是否可由容器写入。如果是,则 udev 会自动启动并破坏非特权容器中的 IPv4。请参阅commit bf331d8 和 linuxcontainers 上的讨论。
在 2020 年之后创建的容器上,应该已经存在 systemd-networkd.service
覆盖来解决此问题,如果不存在,则创建它
/etc/systemd/system/systemd-networkd.service.d/lxc.conf
[Service] BindReadOnlyPaths=/sys
您也可以通过在容器的配置文件中设置 raw.lxc: lxc.mount.auto = proc:rw sys:ro
来解决此问题,以确保 /sys
对于整个容器都是只读的,尽管这可能存在问题,如上面链接的讨论中所述。
ufw 没有网络连接
当在安装了 ufw 的系统上运行 LXD 时,lxc ls
的输出将包含一个空的 IPv4 字段,出站请求不会转发到容器外部,入站请求也不会转发到容器内部。正如在 LXC Discourse 实例上的一个帖子 中看到的,ufw 默认会阻止来自 LXD 网桥的流量。解决方案是为每个网桥配置两个新的 ufw 规则
# ufw route allow in on lxdbr0 # ufw allow in on lxdbr0
有关这两个命令的更多信息,请查看此帖子,其中更详细地描述了这些命令及其局限性。
安装 Docker 后没有网络连接
您在主机上安装了 Docker,并且无法从 lxc 容器内访问 LAN 或互联网。
# iptables -I DOCKER-USER -i lxdbr0 -o interface -j ACCEPT # iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
在第一行中,将 interface
替换为外部网络接口(将主机连接到 LAN/互联网的接口,例如 enp6so
、wlp5s0
等)。如果需要,也请替换 lxdbr0
。
有关更多详细信息,请参阅LXD 文档中的此注释。
使用 snapcraft 构建 snap:craft-providers 错误:LXD 需要额外的权限。
如果您收到以下错误
craft-providers error: LXD requires additional permissions. Ensure that the user is in the 'lxd' group. Visit https://documentation.ubuntu.com/lxd/en/latest/getting_started/ for instructions on installing and configuring LXD for your operating system. Full execution log: '/home/your_user/.local/state/snapcraft/log/snapcraft-20231129-221308.209638.log'
如果您尝试使用 snapcraft
命令构建 snap,则可能会发生这种情况。如果您已将自己添加到 lxd 组并重新启动后错误仍然存在,请尝试通过 snap 而不是作为 Arch 软件包安装 lxd(不要同时安装两者),这可能会解决此问题。
卸载
停止 并禁用 lxd.service
和 lxd.socket
。然后卸载 lxd 软件包。
如果您在未禁用服务的情况下卸载了软件包,则 /etc/systemd/system/multi-user.wants/lxd.service
处可能存在残留的损坏的符号链接。
如果要删除所有数据
# rm -r /var/lib/lxd
如果您使用了任何示例网络配置,则还应删除这些配置。