交叉编译多拱容器

时间:2017-12-05 03:18:33

标签: docker arm raspberry-pi3

我正在尝试构建一个ARM(arm32v7)容器,但使用的是x86_64主机。虽然我知道有一些非常酷的东西,比如Resin使用Qemu shenanigans,Multiarch进行通用容器的交叉构建,但我有一个小问题:我尝试构建的容器开始作为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图像开始构建?

1 个答案:

答案 0 :(得分:1)

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

让我们一步一步地完成这个步骤。首先,让我们为Docker客户端启用实验模式,通过向docker manifest添加以下选项来启用~/.docker/config.json

{
    "experimental": "enabled"
}

然后,我们可以使用docker manifest inspect debian:stretch来显示包含我们要为其构建的体系结构中的图像摘要的fat manifest。例如,arm32v7图像在"architecture": "arm"键下指定了"variant": "v7"platform。使用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)将其外部化。