使用buildx在x86机器上面编译arm64架构的Docker镜像

Posted 济南小老虎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用buildx在x86机器上面编译arm64架构的Docker镜像相关的知识,希望对你有一定的参考价值。

buildx 多架构编译


安装docker

下载docker
下载buildx
安装架构支持
docker run --privileged --rm tonistiigi/binfmt --install all

创建一个自己的空间
buildx create --use --name mybuilder

检查支持的架构
buildx inspect mybuilder --bootstrap

Nodes:
Name:      mybuilder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Buildkit:  v0.11.6
Platforms: linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

打包镜像

dockerfile 的信息为:
# 注意from 好像不能写带架构的. 会根据platform自动进行下载. 比较简单. 


FROM docker.io/adoptopenjdk/openjdk8
WORKDIR /app
COPY /app /app
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dloader.path=./server/runtime/3rd,./server/runtime/libs","-Dparallel.startup=true","-Dserver.runtime.path.name=server","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=75.0","-XX:InitialRAMPercentage=75.0","-XX:MinRAMPercentage=75.0","-XX:-DisableExplicitGC","-XX:+PrintGC","-XX:+PrintGCDateStamps","-XX:+PrintGCDetails","-XX:+PrintGCTimeStamps","-Xloggc:/app/dump/gclog","-XX:+HeapDumpOnOutOfMemoryError","-XX:HeapDumpPath=/app/dump","-jar","./server/runtime/caf-bootstrap.jar","--spring.config.location=./server/runtime/"]


buildx build -t zhaobsh:arm64 --platform=linux/arm64 -o type=docker .
buildx build -t zhaobsh:amd64 --platform=linux/amd64 -o type=docker .

我在arm上面搭建的就不行没法运行amd64的

docker run -it zhaobsh:amd64
WARNING: The requested image\'s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
java: error while loading shared libraries: libpthread.so.0: ELF load command alignment not page-aligned

然后 arm64自己的进行验证



可以直接push操作

buildx build -t harbor.xxxx.com/library/zhaobsh  --platform=linux/arm,linux/arm64,linux/amd64 . --push

# 这个我还没测试

迁移测试

docker save zhaobsh:amd64 |gzip > zhaobsh_amd64.tgz 
然后在amd64的机器上面进行验证. 

也可以使用如下命令进行检查具体的架构信息: 

[root@auto02 docker]# docker inspect zhaobsh:amd64 |grep Architecture
        "Architecture": "amd64",
[root@auto02 docker]# docker inspect zhaobsh:arm64 |grep Architecture
        "Architecture": "arm64",
[root@auto02 docker]# 

Docker - 无法使用 docker buildx 构建多平台映像

【中文标题】Docker - 无法使用 docker buildx 构建多平台映像【英文标题】:Docker - Cannot build multi-platform images with docker buildx 【发布时间】:2020-05-21 15:09:14 【问题描述】:

我正在尝试使用 docker buildx 构建多平台(amd64、arm64 和 armv7)映像。由于我使用的是运行 Ubuntu 18.04 的 amd64 机器,因此我按照 Docker website 上的说明安装了 qemu 通过:

sudo apt install qemu-user

但是,当我执行上一个命令时,出现了一个奇怪的错误。更具体地说,binfmt-support 服务似乎存在问题。这是完整的日志:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
The following additional packages will be installed:
  binfmt-support qemu-user-binfmt
The following NEW packages will be installed:
  binfmt-support qemu-user qemu-user-binfmt
0 upgraded, 3 newly installed, 0 to remove and 1 not upgraded.
Need to get 0 B/7.409 kB of archives.
After this operation, 63,4 MB of additional disk space will be used.
Do you want to continue? [Y/n] 
Selecting previously unselected package binfmt-support.
(Reading database ... 245278 files and directories currently installed.)
Preparing to unpack .../binfmt-support_2.1.8-2_amd64.deb ...
Unpacking binfmt-support (2.1.8-2) ...
Selecting previously unselected package qemu-user.
Preparing to unpack .../qemu-user_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ...
Unpacking qemu-user (1:2.11+dfsg-1ubuntu7.21) ...
Selecting previously unselected package qemu-user-binfmt.
Preparing to unpack .../qemu-user-binfmt_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ...
Unpacking qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ...
Setting up binfmt-support (2.1.8-2) ...
Job for binfmt-support.service failed because the control process exited with error code.
See "systemctl status binfmt-support.service" and "journalctl -xe" for details.
invoke-rc.d: initscript binfmt-support, action "start" failed.
● binfmt-support.service - Enable support for additional executable binary formats
   Loaded: loaded (/lib/systemd/system/binfmt-support.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Wed 2020-02-05 17:20:29 CET; 4ms ago
     Docs: man:update-binfmts(8)
  Process: 7766 ExecStart=/usr/sbin/update-binfmts --enable (code=exited, status=2)
 Main PID: 7766 (code=exited, status=2)

feb 05 17:20:29 XPS-15-9570 systemd[1]: Starting Enable support for additional executable binary formats...
feb 05 17:20:29 XPS-15-9570 update-binfmts[7766]: update-binfmts: warning: unable to close /proc/sys/fs/binfmt_misc/register: No such file or directory
feb 05 17:20:29 XPS-15-9570 update-binfmts[7766]: update-binfmts: exiting due to previous errors
feb 05 17:20:29 XPS-15-9570 systemd[1]: binfmt-support.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
feb 05 17:20:29 XPS-15-9570 systemd[1]: binfmt-support.service: Failed with result 'exit-code'.
feb 05 17:20:29 XPS-15-9570 systemd[1]: Failed to start Enable support for additional executable binary formats.
Setting up qemu-user (1:2.11+dfsg-1ubuntu7.21) ...
Setting up qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ...
update-binfmts: warning: current package is qemu-user-binfmt, but binary format already installed by qemu-user-static
update-binfmts: exiting due to previous errors
dpkg: error processing package qemu-user-binfmt (--configure):
 installed qemu-user-binfmt package post-installation script subprocess returned error exit status 2
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for neon-settings (0.0+p18.04+git20191212.1343) ...
Processing triggers for systemd (237-3ubuntu10.33) ...
Errors were encountered while processing:
 qemu-user-binfmt
E: Sub-process /usr/bin/dpkg returned an error code (1)

尽管如此,我还是尝试按照通常的程序进行,即:

docker buildx create --name mybuilder
docker buildx use mybuilder
docker buildx inspect --bootstrap

最后一条命令的输出在哪里:

[+] Building 5.0s (1/1) FINISHED                                                                                                                                                             
 => [internal] booting buildkit                                                                                                                                                         5.0s
 => => pulling image moby/buildkit:buildx-stable-1                                                                                                                                      4.3s
 => => creating container buildx_buildkit_mybuilder0                                                                                                                                    0.7s
Name:   mybuilder
Driver: docker-container

Nodes:
Name:      mybuilder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/amd64, linux/386

如您所见,“linux/amd64”和“linux/386”被列为唯一可用的平台,但是我需要为“linux/arm64”和“linux/arm/v7”平台构建映像也是。 几个小时以来,我一直在寻找解决此问题的方法,但没有找到任何可行的方法


------------------------------------ 编辑 ---------- --------------------------

看起来我可以通过运行解决部分问题:

sudo apt purge --auto-remove qemu-user qemu-user-binfmt binfmt-support

然后重新安装它们。事实上,再次运行这个命令:

sudo apt install qemu-user

完全没有错误:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
The following additional packages will be installed:
  binfmt-support qemu-user-binfmt
The following NEW packages will be installed:
  binfmt-support qemu-user qemu-user-binfmt
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/7.409 kB of archives.
After this operation, 63,4 MB of additional disk space will be used.
Do you want to continue? [Y/n] 
Selecting previously unselected package binfmt-support.
(Reading database ... 245437 files and directories currently installed.)
Preparing to unpack .../binfmt-support_2.1.8-2_amd64.deb ...
Unpacking binfmt-support (2.1.8-2) ...
Selecting previously unselected package qemu-user.
Preparing to unpack .../qemu-user_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ...
Unpacking qemu-user (1:2.11+dfsg-1ubuntu7.21) ...
Selecting previously unselected package qemu-user-binfmt.
Preparing to unpack .../qemu-user-binfmt_1%3a2.11+dfsg-1ubuntu7.21_amd64.deb ...
Unpacking qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ...
Setting up binfmt-support (2.1.8-2) ...
Created symlink /etc/systemd/system/multi-user.target.wants/binfmt-support.service → /lib/systemd/system/binfmt-support.service.
Setting up qemu-user (1:2.11+dfsg-1ubuntu7.21) ...
Setting up qemu-user-binfmt (1:2.11+dfsg-1ubuntu7.21) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for neon-settings (0.0+p18.04+git20191212.1343) ...
Processing triggers for systemd (237-3ubuntu10.38) ...

同样,systemctl status binfmt-support.service 的输出也符合预期:

● binfmt-support.service - Enable support for additional executable binary formats
   Loaded: loaded (/lib/systemd/system/binfmt-support.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2020-02-10 11:42:23 CET; 1min 11s ago
     Docs: man:update-binfmts(8)
 Main PID: 7161 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 4915)
   CGroup: /system.slice/binfmt-support.service

feb 10 11:42:23 XPS-15-9570 systemd[1]: Starting Enable support for additional executable binary formats...
feb 10 11:42:23 XPS-15-9570 systemd[1]: Started Enable support for additional executable binary formats.

但是,部分问题仍然存在,运行这三个命令后的输出:

docker buildx create --name mybuilder
docker buildx use mybuilder
docker buildx inspect --bootstrap

和之前一样,即:

[+] Building 2.6s (1/1) FINISHED                                                                                                                                                             
 => [internal] booting buildkit                                                                                                                                                         2.6s
 => => pulling image moby/buildkit:buildx-stable-1                                                                                                                                      2.0s
 => => creating container buildx_buildkit_mybuilder0                                                                                                                                    0.6s
Name:   mybuilder
Driver: docker-container

Nodes:
Name:      mybuilder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/amd64, linux/386

这是为什么呢?为什么它向我显示 linux/amd64linux/386 作为唯一可用的平台?


编辑#2(关于@LinPy 的评论)

docker context ls 的输出为:

NAME                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm

我也尝试在 qemu 安装后重新启动 docker,但没有成功。另外,在 docker buildx 命令中指定目标平台:

docker buildx build -t <mytag> --platform linux/amd64,linux/arm64,linux/arm/v7 --load .

导致此错误:

[+] Building 0.6s (5/20)                                                                                                      
 => [internal] load .dockerignore                                                                                        0.0s
 => => transferring context: 2B                                                                                          0.0s
 => [internal] load build definition from Dockerfile                                                                     0.0s
 => => transferring dockerfile: 32B                                                                                      0.0s
 => [linux/arm/v7 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2                                   0.6s
 => CANCELED [linux/arm64 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2                           0.6s
 => CANCELED [linux/amd64 internal] load metadata for docker.io/alegeno92/opencv_python3:3.4.2                           0.6s
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to load LLB: runtime execution on platform linux/arm/v7 not supported

顺便说一下,我的内核版本是4.15.0-76-generic

【问题讨论】:

【参考方案1】:

首先运行多架构容器

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker buildx rm builder
docker buildx create --name builder --driver docker-container --use
docker buildx inspect --bootstrap

你应该有你的替代架构。

【讨论】:

链接到 multiarch/qemu-user-static 存储库:github.com/multiarch/qemu-user-static【参考方案2】:

标记此答案以响应第一个错误。命令已根据https://docs.docker.com/buildx/working-with-buildx/ 更新。

QEMU 是一个跨平台仿真器,负责为不同架构(通过 binfmt_misc 处理程序)获取二进制文件。

这将为一些人节省一些时间来首先使用此命令:

docker run --privileged --rm tonistiigi/binfmt --install all

【讨论】:

以上是关于使用buildx在x86机器上面编译arm64架构的Docker镜像的主要内容,如果未能解决你的问题,请参考以下文章

Docker镜像多架构构建

Docker镜像多架构构建

x86的库和arm的.o文件能链接吗

Docker - 无法使用 docker buildx 构建多平台映像

buildx 简介以及安装

为arm64交叉编译googletest