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

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

问题描述

我正在尝试构建一个ARM(arm32v7)容器,但使用的是x86_64主机.虽然我知道有些很酷的事情,例如 Resin 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客户端启用实验模式,通过向~/.docker/config.json添加以下选项来启用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行中的硬编码摘要,可以通过

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天全站免登陆