我想使用 LXD 从运行 ubuntu 16.04 的 AMD64 主机引导根文件系统,以便部署到嵌入式 ARM 系统上。以前,我使用脚本和命令完成了这项工作chroot
,但我使用的脚本容易出错,并且有删除 /dev 条目的坏习惯。
我已经能够使用 本地复制映像lxc image copy images:ubuntu/16.04/arm64 --alias=ubuntu-server-arm64
,并安装了 qemu-user-static,但无法从此映像实际启动容器。我收到以下错误:
$ lxc launch ubuntu-server-arm64 bootstrap
Creating bootstrap
error: Requested architecture isn't supported by this host
有没有办法强制 lxd 忽略架构不匹配并用来
qemu-user-static
运行子容器?
答案1
我能够让一个外部架构与 LXD 一起工作。我拿了一个 ARMv7 镜像,从中创建了一个 squashfs,并添加到qemu-arm-static
下/usr/bin
。让它与 LXD 一起工作的诀窍是让元数据 tarball 说明镜像是 x86_64(或任何主机架构)。导入并运行此镜像有效,LXD 认为它是一个受支持的架构(与主机匹配),并且它能够运行,因为qemu-arm-static
和binfmt
。
ALPINE_MIRROR_URL="http://ams.edge.kernel.org/alpine"
ALPINE_VERSION="3.11.5"
ALPINE_ARCH="armhf"
version=$(echo $ALPINE_VERSION | cut -d '.' -f 1-2)
curl -O ${ALPINE_MIRROR_URL}/v${version}/releases/${ALPINE_ARCH}/alpine-minirootfs-${ALPINE_VERSION}-${ALPINE_ARCH}.tar.gz
ROOTFS=alpine-rootfs
mkdir ${ROOTFS}
tar xzf alpine-minirootfs-${ALPINE_VERSION}-${ALPINE_ARCH}.tar.gz -C ${ROOTFS}
cp /usr/bin/qemu-arm-static ${ROOTFS}/usr/bin/
mksquashfs ${ROOTFS} rootfs.squashfs
lxc import meta.tar.xz rootfs.squashfs --alias crossx
lxc launch crossx x
lxc exec x -- uname -a
Linux x 4.15.0-50-generic #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019 armv7l Linux
lxc image ls
| crossx | 1e5e5a2dafb8 | no | Alpinelinux x86_64 (20200330_1354) | x86_64 | CONTAINER | 5.45MB | Apr 2, 2020 at 6:25pm (UTC) |
您可以在最后两个命令中看到容器确实是armv7l
x86_64,但 LXD 认为它是 x86_64。
答案2
据负责 LXC/LXD 项目的 Stephane Graber 称(在回答我关于他们讨论网站):
qemu-user-static 是一个 binfmt 助手,可让您在架构之间进行即时转换。它可让您有效地运行当前架构以外的架构的二进制文件。
qemu-user-static 本身可以在容器内正常工作,并允许您在其中运行一些外部架构的二进制文件。
尝试通过 qemu-user-static 运行整个容器是非常不切实际的,因为 qemu-user-static 有一些很大的限制,例如,任何依赖于 ptrace(初始化系统和调试工具)、netlink(所有网络工具和一些初始化系统)或线程(更多软件)的东西通常都会失败。
我在 LXC 中实施的方法是创建一个混合容器,其中大多数软件包属于外部架构,但 init 系统、网络工具等属于本机架构。这种方法虽然有效,但也不是特别有用,更不用说速度非常慢了。
由于就我们而言这实际上是不支持的,因此我们不为 LXD 提供任何外部架构映像。但是,您可以通过组装外部架构的 rootfs 来构建自己的映像,然后包括所需的 qemu-user-static 二进制文件,替换任何无法与仿真配合使用的二进制文件,并将其生成为 LXD 映像(用其预期运行的架构而不是其包含的架构来标记它)。
因此,实际上,尝试在 LXD 上运行外部架构是不受支持的,而 LXC 方法或多或少是一种“混合环境”类型的黑客攻击。
这听起来好像也可以做到,但需要你创建一个外部架构的根文件系统,并基本上自己创建运行所有这些的“图像”,由于各种原因,这可能会很令人头痛,而且需要做大量工作才能完成。