【问题标题】:Cross-compile multi-arch containers交叉编译多架构容器
【发布时间】:2017-12-05 03:18:32
【问题描述】:

我正在尝试构建一个 ARM (arm32v7) 容器,但使用的是 x86_64 主机。虽然我知道有一些很酷的东西,比如 Resin 使用 Qemu 恶作剧,Multiarch 用于交叉构建通用容器,但我有一个小问题:我正在尝试构建的容器从多架构开始,所以 Docker总是在 FROM 指令中选择 x86 图像。

我想在 x86 主机上从 Multi-arch Rust image 构建一个 ARM 容器。问题是,我找不到任何文档来明确说我想从 ARM 容器开始并从中构建,而不是 x86 容器。此外,图像上的标签不会消除歧义,因此我不能使用它们来选择起始容器。

我尝试编辑 /etc/docker/daemon.json 文件以包含:

{
    "labels": [ "os=linux", "arch=arm32v7" ],
    "experimental": true
}

但这根本没有帮助。 docker pull 仍然检索 x86 图像。所有这一切的目的是提高最终在 Raspberry Pi 上运行的容器的编译时间;就目前而言,编译时间非常慢。

有什么方法可以明确表示我想从 ARM 映像开始构建?

【问题讨论】:

标签: docker arm raspberry-pi3


【解决方案1】:

可以为另一个架构构建简单的 Docker 容器(“交叉编译”),方法是使用适合该架构的基础镜像。简单来说,我的意思是不需要在其 Dockerfile 中构建 RUN 命令的图像。这是因为 Docker 没有能力在另一个架构的容器中实际运行命令。虽然这听起来有限制,但当与 multi-stage builds 结合使用以交叉编译代码时,它会非常强大。

让我们一步一步来看看。首先,让我们为 Docker 客户端启用实验模式以启用docker manifest,方法是将以下选项添加到~/.docker/config.json

{
    "experimental": "enabled"
}

然后我们可以使用docker manifest inspect debian:stretch 显示fat manifest,其中包含我们要构建的架构中的图像摘要。例如,arm32v7 映像在 platform 键下指定了 "architecture": "arm""variant": "v7"。使用jq,我们可以通过编程方式提取此图像的摘要:

docker manifest inspect debian:stretch | jq -r '.manifests[] | select(.platform.architecture == "arm" and .platform.variant == "v7") | .digest'`

然后可以在 Dockerfile 中的 FROM 命令中使用此摘要:

FROM debian@sha256:d01d682bdbacb520a434490018bfd86d76521c740af8d8dbd02397c3415759b1

然后可以将COPY 交叉编译的二进制文件放入镜像中。该二进制文件可能来自您机器上的交叉编译器,也可能来自多阶段构建中的另一个容器。要摆脱 Dockerfile 的 FROM 行中的硬编码摘要,可以通过 Docker build argument (ARG) 将其外部化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 2015-12-23
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多