一个伪linux粉丝的blog

  1. 首页
  2. unix/linux
  3. 正文

Building-Multi-architecture-Docker-Images-With-Buildx

23 7 月, 2020 1050点热度 0人点赞 0条评论

1. 背景

最近看到公司开始发布支持 arm系统的镜像包,找到几篇文章(链接见最后),发现即使手上没有 arm 系统环境也能同时构建这种包了,正好前一阵升级过19.03 ,有这个基础,于是实践一下,使用 Buildx 构建多种系统架构的镜像。

2. 步骤

Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 Moby BuildKit 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。
BuildKit 是下一代的镜像构建组件,主要特点有很多,本文主要使用其可以编译多种系统架构的特性。
网址:https://github.com/moby/buildkit
:lol: 需要注意的是,该功能仅适用于 Docker v19.03+ 版本 ,以及系统内核版本需要大于 4.8,这个地方的坑也只有我这个老环境才能遇到。

查看版本信息,我的环境Docker 最新版本号是 19.03.11。

[root@dc1-m2 ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.11
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        42e35e61f3
 Built:             Mon Jun  1 09:13:48 2020
 OS/Arch:           linux/amd64
 Experimental:      true
Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       0ae5cfe45f
  Built:            Tue Mar 24 08:25:36 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

 

2.1. 启用 Buildx

buildx 命令属于实验特性,因此首先需要开启该特性。
编辑 ~/.docker/config.json 文件,新增如下内容(以下的演示适用于事先不存在 .docker 目录的情况下),如果本身有config.json文件,直接加1行 "experimental": "enabled" 就好

$ mkdir ~/.docker
$ cat > ~/.docker/config.json <<EOF
{
"experimental": "enabled"
}
EOF

Linux/macOS 下或者通过设置环境变量的方式(不推荐):

1
<span class="pln">$ export DOCKER_CLI_EXPERIMENTAL</span><span class="pun">=</span><span class="pln">enabled</span>

2.2. 新建 builder 实例

在 Docker 19.03+ 版本中可以使用 docker buildx build 命令使用 BuildKit 构建镜像。该命令支持 --platform 参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。

Docker 在 Linux 系统架构下是不支持 arm 架构镜像,因此我们可以运行一个新的容器让其支持该特性,Docker 桌面版(windows、macos)无需进行此项设置。

$ docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64

注:docker/binfmt 可以参考网址:https://hub.docker.com/r/docker/binfmt/tags 获取最新镜像,最新的tag就是上面这个,5个月前的版本。

(悲伤) 上面docker run ** docker/binfmt ** 命令遇到一个报错 2020/07/16 05:46:01 Cannot write to /proc/sys/fs/binfmt_misc/register: write /proc/sys/fs/binfmt_misc/register: invalid argument

搜了很久,当时没找到解决方法, 隔天才发现是系统内核必须要大于4.8。

庆幸的是,测试环境3台当中有1台可以正常运行,系统分别是  CentOS Linux release 7.8.2003 (Core)、CentOS Linux release 7.6.1810 (Core)、 Red Hat Enterprise Linux Server release 7.8 (Maipo) 正常运行,后来想想应该是内核版本差异,见另一篇 https://blog.wanjie.info/2020/07/how-to-upgrade-kernel-centos/。

由于 Docker 默认的 builder 实例不支持同时指定多个 --platform ,我们必须首先创建一个新的 builder 实例。

1
<span class="pln">$ docker buildx create </span><span class="pun">--</span><span class="pln">name mybuilder </span><span class="pun">--</span><span class="pln">driver docker</span><span class="pun">-</span><span class="pln">container</span>

返回新的 builder 实例名,为「mybuilder」

1
<span class="pln">mybuilder</span>

使用新创建好的 builder 实例

1
<span class="pln">$ docker buildx use mybuilder</span>

查看已有的 builder 实例

[root@instance-20200607-0734 ~]# docker buildx ls
NAME/NODE    DRIVER/ENDPOINT             STATUS   PLATFORMS
mybuilder *  docker-container
  mybuilder0 unix:///var/run/docker.sock inactive
default      docker
  default    default                     running  linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

另外我们查看目录 /proc/sys/fs/binfmt_misc/ 会发现多了一些架构支持。

qemu-aarch64 qemu-arm qemu-ppc64le qemu-riscv64 qemu-s390x  ...

2.3.  新建 Dockerfile 文件

要想构建多种系统架构的镜像,还需要一个支持的 Dockerfile 文件。

我们就用最近改造过多次的alpine来实践吧,Dockerfile如下。

FROM --platform=$TARGETPLATFORM alpine:3.12 #加1个平台参数,方便后面指定需要的平台
LABEL MAINTAINER="[email protected]"
ENV TIMEZONE="Asia/Shanghai"              \
    BUILD_DEPS="tzdata \
                curl \
                sudo \
                bash \
                dnscache \
                openssh-client \
                sshpass \
                acl"
RUN apk update                                              && \
    apk upgrade                                             && \
    apk add --no-cache ${BUILD_DEPS}                        && \
    cp -rfv  /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && \
    echo ${TIMEZONE} > /etc/timezone                        && \
    apk del tzdata                                          && \
    rm -rf /var/cache/apk/*
CMD ["/bin/bash"]

$TARGETPLATFORM 是内置变量,由 --platform 参数来指定其值。

2.4.  构建镜像

在本地构建支持 2 种 platform 的镜像  amd64 和 arm v7

docker buildx build --platform linux/amd64,linux/arm/v7 -t cnrock/alpine -o type=local,dest=~/.docker .

构建日志如下,可以看到当中有2个打包过程 linux/amd64 1/2  和 linux/arm/v7 1/2

[+] Building 25.9s (9/9) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                      0.1s
 => => transferring dockerfile: 869B                                                                                                                      0.0s
 => [internal] load .dockerignore                                                                                                                         0.1s
 => => transferring context: 2B                                                                                                                           0.0s
 => [linux/arm/v7 internal] load metadata for docker.io/library/alpine:3.12                                                                               3.4s
 => [linux/amd64 internal] load metadata for docker.io/library/alpine:3.12                                                                                7.5s
 => [linux/amd64 1/2] FROM docker.io/library/alpine:3.12@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321                          7.5s
 => => resolve docker.io/library/alpine:3.12@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321                                      0.0s
 => => sha256:df20fa9351a15782c64e6dddb2d4a6f50bf6d3688060a34c4014b0d9a752eb4c 2.80MB / 2.80MB                                                            3.5s
 => => sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e 1.51kB / 1.51kB                                                            0.0s
 => => sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321 1.64kB / 1.64kB                                                            0.0s
 => => sha256:a15790640a6690aa1730c38cf0a440e2aa44aaca9b0e8931a9f2b0d7cc90fd65 528B / 528B                                                                0.0s
 => => unpacking docker.io/library/alpine:3.12@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321                                    0.7s
 => [linux/arm/v7 1/2] FROM docker.io/library/alpine:3.12@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321                         0.0s
 => => resolve docker.io/library/alpine:3.12@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321                                      0.0s
 => CACHED [linux/arm/v7 2/2] RUN apk update                                              &&     apk upgrade                                              0.0s
 => [linux/amd64 2/2] RUN apk update                                              &&     apk upgrade                                             &&       5.8s
 => exporting to client                                                                                                                                   5.0s
 => => copying files linux/arm/v7 10.52MB                                                                                                                 5.0s
 => => copying files linux/amd64 14.68MB                                                                                                                  4.5s

docker buildx build 的具体参数含义,参考下面的官方文档

https://docs.docker.com/engine/reference/commandline/buildx_build/

做完上面的那一步,实际上是把构建好的镜像放在了本地路径下。

上面这个命令还有一个很骚的操作,打包完成后直接上传到 hub.docker.com,只需登录后,去掉本地存储,在命令最后面加1个 --push 即可。

命令如下 :docker buildx build --platform linux/amd64,linux/arm/v7 -t cnrock/alpine . --push

2.4.1. 查看镜像信息1

打开hub.docker.com 网站检查一下,发现确实是我上传的2种架构的 alpine 自定义镜像

2.4.2. 查看镜像信息2

命令行方式检查一下  docker buildx imagetools inspect  cnrock/alpine 发现确实有 2种架构的 alpine 自定义镜像

打包成功,找个arm环境试下效果吧。

 

3. 参考链接

https://www.docker.com/blog/multi-platform-docker-builds/

https://docs.docker.com/docker-for-mac/multi-arch/

1
<a class="external-link" href="https://teddysun.com/581.html" target="_blank" rel="nofollow noopener noreferrer" data-ext-link-init="true">使用 Docker Buildx 构建多种系统架构镜像</a>

如何构建多架构 Docker 镜像?

https://nexus.eddiesinentropy.net/2020/01/12/Building-Multi-architecture-Docker-Images-With-Buildx/

https://github.com/docker/buildx

https://phoenixnap.com/kb/how-to-upgrade-kernel-centos

 

相关文章:

  1. Android 4.4.2 cm11 error: Device Offline
  2. how-to-upgrade-kernel-centos
  3. docker-upgrade
  4. Docker "fork/exec /proc/self/exe: no such file or directory\""
标签: buildx
最后更新:23 7 月, 2020

wanjie

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

This site uses Akismet to reduce spam. Learn how your comment data is processed.

归档
分类
  • network / 332篇
  • Uncategorized / 116篇
  • unix/linux / 121篇
  • 业界资讯 / 38篇
  • 公司杂事 / 11篇
  • 数码影像 / 12篇
  • 美剧 / 3篇
  • 美图共赏 / 21篇
  • 英语学习 / 3篇
标签聚合
wget 天翼live dreamhost Google Voice Nginx postgres jira nexus docker gitlab Ubuntu 网站运营 kernel dreamhost空间 泰国 deepseek 浏览器 ldap kubectl ssh VPS d90 google-chrome 虚拟主机 openssl Google debian squid k8s 邮件归档

COPYRIGHT © 2008-2025 wanjie.info. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang