交叉编译多架构容器 [英] Cross-compile multi-arch containers

查看:18
本文介绍了交叉编译多架构容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to build an ARM (arm32v7) container, but using an x86_64 host. While I know there are some pretty cool things like Resin using Qemu shenanigans, and Multiarch for doing crossbuilding of generic containers, I have a slight issue: The container I'm trying to build starts off as multiarch, and so Docker always chooses the x86 image in the FROM instruction.

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

I want to build an ARM container from a Multi-arch Rust image on an x86 host. The problem is, I can't find any documentation to explicitly say I want to start with the ARM container and build from that, not the x86 container. Additionally, the tags on the image don't disambiguate, so I can't use those to select the starting container.

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

I've tried editing the /etc/docker/daemon.json file to contain:

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

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

but that hasn't helped at all. docker pull still retrieves the x86 images. The purpose of all this is to boost compile times for containers ultimately running on Raspberry Pi; compile times are super slow as it stands.

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

Are there any ways to explicitly say that I want to build starting with the ARM image?

推荐答案

通过使用适用于该架构的适当基础映像,可以为该架构(交叉编译")构建简单的 Docker 容器.简单来说,我的意思是不需要在其 Dockerfile 中使用 RUN 命令构建的图像.这是因为 Docker 没有能力在容器中为另一种架构实际运行命令.虽然这听起来有限制,但当与 多阶段构建结合使用时,它会非常强大 交叉编译代码.

It is possible to build simple Docker containers for another architecture ("cross-compile") by using an appropriate base image for that architecture. By simple, I mean images that don't need a RUN command in their Dockerfile to be built. This is because Docker doesn't have the ability to actually run commands in a container for another architecture. While this sounds restrictive, it can be quite powerful when combined with multi-stage builds to cross-compile code.

让我们逐步完成此过程.首先,让我们通过在 ~/.docker/config.json 中添加以下选项来为我们的 Docker 客户端启用实验模式以启用 docker manifest:

Let's walk through this step-by-step. First off, let's enable experimental mode for our Docker client to enable docker manifest by adding the following option to ~/.docker/config.json:

{
    "experimental": "enabled"
}

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

We can then use docker manifest inspect debian:stretch to show the fat manifest that contains a digest for the image in the architecture we want to build for. For example, the arm32v7 image has "architecture": "arm" and "variant": "v7" specified under the platform key. Using jq, we can extract the digest for this image programatically:

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

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

This digest can then be used in the FROM command in a Dockerfile:

FROM debian@sha256:d01d682bdbacb520a434490018bfd86d76521c740af8d8dbd02397c3415759b1

然后就可以COPY 交叉编译的二进制文件到图像中.该二进制文件可能来自您机器上的交叉编译器,也可能来自多阶段构建中的另一个容器.要摆脱 Dockerfile 的 FROM 行中的硬编码摘要,可以通过 Docker 构建参数 (ARG).

It is then possible to COPY cross-compiled binary into the image. This binary could come from a cross-compiler on your machine or from another container in a multi-stage build. To get rid of the hard-coded digest in the Dockerfile's FROM line, it's possible to externalise it through a Docker build argument (ARG).

这篇关于交叉编译多架构容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆