Docker编译多平台文件、构建多平台镜像并运行

这篇具有很好参考价值的文章主要介绍了Docker编译多平台文件、构建多平台镜像并运行。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考官方文档:

  • Multi-stage
  • Multi-platform
  • Multi-platform images

方法

  如果在 x86_64/amd64 的平台上,想构建适用于多个平台的镜像,例如 linux/amd64linux/arm64,根据官方文档,有三种方法可以使用:

  1. QEMU
      使用 QEMU 模拟构建多平台映像是最简单的入门方法,但可能比本机构建慢得多,特别是对于编译、压缩或解压缩等计算量大的任务。因此如果条件允许的话,更推荐使用 Cross-compilation交叉编译)。但因为使用起来最简单,所以我在x86_64平台上构建arm64镜像并运行容器时用的是这个方法。
  2. Multiple native nodes
      使用多个本机节点可以为 QEMU 无法处理的更复杂的情况提供更好的支持,并且通常具有更好的性能。
  3. Cross-compilation
      交叉编译使多平台构建速度更快、用途更广泛,但必须要有相对应的编译器。

Buildx 设置

  在构建镜像时,是通过设置 --platform 参数来指定目标平台的。例如, linux/amd64linux/arm64darwin/amd64

  默认的构建驱动程序不支持并发多平台构建,一次只能针对一个平台进行构建(例如 docker build --platform=linux/amd64 )。
  如果想同时针对多个平台进行构建(例如 --platform=linux/amd64,linux/arm64 ),则需要创建构建器builder)。
  要使用不同的驱动程序,需要使用 Docker Buildx。 Buildx 是下一代构建客户端,它提供与 docker build 命令类似的用户体验,同时支持其他功能。

  例如创建一个使用docker-container作为驱动程序,名为container的新构建器:

docker buildx create --driver=docker-container --name=container

可以使用 docker buildx ls 命令列出可用的构建器。*标明了当前正在使用的构建器(在下面的示例中为default):

docker buildx ls                                                                                                                                                                                                                                                                                                
NAME/NODE    DRIVER/ENDPOINT             STATUS   BUILDKIT             PLATFORMS
container    docker-container                                          
  container0 unix:///var/run/docker.sock inactive                      
default *    docker                                                    
  default    default                     running  v0.11.7+d3e6c1360f6e linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386

从上面的输出中可以看到,container后的BUILDKITPLATFORMS为空,那么在第一次使用container构建镜像时,就会先下载相关文件,然后才会开始构建。

  也可以提前安装并在创建完成后马上启用构建器。需要用到tonistiigi/binfmt,之后还会自动下载moby/buildkit镜像。

如果电脑重启后在/proc/sys/fs/binfmt_misc中找不到qemu相关内容,那么还需要重新执行这条命令:

docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create --name mybuilder --bootstrap --use

结果如下:

docker buildx ls                                                                                                                                                                                                                                                                                                
NAME/NODE    DRIVER/ENDPOINT             STATUS   BUILDKIT             PLATFORMS
container    docker-container                                          
  container0 unix:///var/run/docker.sock inactive                      
mybuilder *  docker-container                                          
  mybuilder0 unix:///var/run/docker.sock running  v0.12.3              linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default      docker                                                    
  default    default                     running  v0.11.7+d3e6c1360f6e linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

使用QEMU仿真

Docker编译多平台文件、构建多平台镜像并运行,Docker,docker,容器

上图为仿真构建过程。
 

  仿真构建时,需要指定构建器参数 --builder,以及平台参数 --platform

编译文件

  例如下面这条命令用于编译多平台二进制文件:

docker buildx build \
    --target=binaries \
    --output=bin \
    --builder=container \
    --platform=linux/amd64,linux/arm64,linux/arm/v7 .

示例Dockerfile详细内容见Github,需要下载整个仓库然后在仓库根目录执行该命令。

构建镜像

以下示例使用单个 Dockerfile 为多个平台构建了安装有 curl 的 Alpine 映像。

Dockerfile:

# syntax=docker/dockerfile:1
FROM alpine:3.16
RUN apk add curl

构建命令:

docker buildx build \
    --builder=mybuilder \
    --platform=linux/amd64,linux/arm64,linux/arm/v7 \
    --tag=<username>/<image>:latest \
    --push .

  其中 --push 表示构建完毕后推送到仓库。
  必须添加 --push--load 参数,否则会得到警告WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load。意思是构建结果只保存在缓存中,使用 --push 可以将镜像推送到远程仓库,使用 --load 可以将镜像保存在本地。
  需要注意的是,如果参数添加的是 --load 而不是 --push,并且--platform后面跟了多个平台,例如--platform=linux/amd64,linux/arm64,linux/arm/v7,那么还是会得到报错ERROR: docker exporter does not currently support exporting manifest lists,这是因为本地无法保存多个同名的镜像。所以如果要保存构建出的多个平台的镜像到本地,就得分多次执行命令,每次只在 --platform 后添加一个平台,并且每次的 --tag 后面的镜像名称都不同。
  例如为三个平台构建了镜像,就得分三次执行命令:

docker buildx build \
    --builder=mybuilder \
    --platform=linux/amd64 \
    --tag=<username>/<image>_amd64:latest \
    --load .
docker buildx build \
    --builder=mybuilder \
    --platform=linux/arm64 \
    --tag=<username>/<image>_arm64:latest \
    --load .
docker buildx build \
    --builder=mybuilder \
    --platform=linux/arm/v7 \
    --tag=<username>/<image>_arm_v7:latest \
    --load .

  可以使用 docker buildx imagetools 命令检查镜像,前提是镜像已推送到远程仓库。例如:

docker buildx imagetools inspect <username>/<image>:latest
Name:      docker.io/<username>/<image>:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48

Manifests:
  Name:      docker.io/<username>/<image>:latest@sha256:71d7ecf3cd12d9a99e73ef448bf63ae12751fe3a436a007cb0969f0dc4184c8c
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      docker.io/<username>/<image>:latest@sha256:5ba4ceea65579fdd1181dfa103cc437d8e19d87239683cf5040e633211387ccf
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64

  Name:      docker.io/<username>/<image>:latest@sha256:29666fb23261b1f77ca284b69f9212d69fe5b517392dbdd4870391b7defcc116
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v7

  如果是使用 --load 保存到了本地,使用 docker image inspect 命令查看镜像。例如:

docker image inspect <username>/<image>_arm_v7

使用交叉编译(cross-compilation)

Docker编译多平台文件、构建多平台镜像并运行,Docker,docker,容器
https://docs.docker.com/build/guide/images/cross-compilation.png

上图为交叉编译构建过程。
 

编译文件

由于Go语言的编译器支持在编译时通过使用 GOOSGOARCH 环境变量来进行交叉编译,因此可以通过Docker自动将 --platform 的参数解析为构建参数TARGETPLATFORMTARGETOSTARGETARCH,并在Dockerfile中赋值给环境变量,来实现交叉编译。

示例Dockerfile详细内容见Github或官网文档,需要下载整个仓库然后在仓库根目录执行该命令。

构建镜像

Dockerfile示例:

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log

在x86_64上运行arm64容器

  先执行这条命令,确保/proc/sys/fs/binfmt_misc有qemu相关内容:

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

  接下来以运行arm64版本的ubuntu 18.04为例:

  1. 下载镜像
docker pull --platform=linux/arm64 ubuntu:18.04 
  1. 运行
docker run --rm -it ubuntu:18.04

忽略警告WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested

  1. 查看版本等相关信息
uname -a

  hello-world镜像同理:文章来源地址https://www.toymoban.com/news/detail-806713.html

docker run --rm --platform=linux/arm64 hello-world
docker run --rm --platform=linux/arm64 hello-world                         

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

到了这里,关于Docker编译多平台文件、构建多平台镜像并运行的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • x86 平台利用 qemu-user-static 实现 arm64 平台 docker 镜像的运行和构建

    因为国产化的普及,尤其一些证券和银行行业,已经开始走信创的路线,后期也许会接触到国产 CPU ( arm 平台,比如华为的鲲鹏处理器) 自己买 arm 平台的 CPU ,这个成本着实吃不消,于是尝试 x86 平台运行 arm 平台的容器来降本增效 docker 运行其他平台容器,需要使用 --pla

    2024年02月02日
    浏览(45)
  • Docker学习路线7:构建容器镜像

    容器镜像是可执行的软件包,包括运行应用程序所需的所有内容:代码、运行时、系统工具、库和设置。通过构建自定义镜像,您可以在任何支持Docker的平台上无缝地部署应用程序及其所有依赖项。 构建容器镜像的关键组件是 Dockerfile 。它本质上是一个包含有关如何组装 D

    2024年02月16日
    浏览(53)
  • 手动构建自己的docker容器镜像实战

    之前的实战中,我们实战中,我们使用的镜像都是镜像仓库已有的镜像。 已有的镜像都是别人已经开发好上传的。今天我们一起来看看如何构建自己的镜像并上传到镜像仓库中。 🏠个人主页:我是沐风晓月 🧑个人简介:大家好,我是沐风晓月,阿里云社区博客专家😉😉

    2023年04月10日
    浏览(37)
  • Docker入门流程(创建容器到构建镜像)

    平时我们经常会遇到在自己电脑上运行的代码,在别人的电脑上运行就出现莫名其妙的问题,这种大多是因为代码”水土不服“,不同电脑的软件版本和依赖库不同,Docker的使用可以很好地解决这个问题。简单来说,Docker可以把 代码和代码运行的环境 一把打包,构建一个容

    2024年02月08日
    浏览(44)
  • Docker进阶:容器数据卷与Dockerfile构建镜像(发布)

    💖The Begin💖点点关注,收藏不迷路💖 1、完成数据持久化和共享数据,docker容器中的数据,同步到本地。 2、重要数据back_up 特点: 实时生效、数据卷可在容器之间共享和重用数据、数据卷中的更改不会包含在镜像更新中、数据卷的生命周期会一直延续到没有容器使用它为止

    2024年02月09日
    浏览(52)
  • Docker基础入门:容器数据卷与Dockerfile构建镜像(发布)

    💖The Begin💖点点关注,收藏不迷路💖 1、完成数据持久化和共享数据,docker容器中的数据,同步到本地。 2、重要数据back_up 特点: 实时生效、数据卷可在容器之间共享和重用数据、数据卷中的更改不会包含在镜像更新中、数据卷的生命周期会一直延续到没有容器使用它为止

    2024年02月10日
    浏览(52)
  • Docker 仓库与注册表: 构建可靠的容器镜像生态系统

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月17日
    浏览(48)
  • 逸学Docker【java工程师基础】2.Docker镜像容器基本操作+安装MySQL镜像运行

    在这里我们的应用程序比如redis需要构建成镜像, 它作为一个Docker文件就可以进行 构建 ,构建完以后他是在 本地的 ,我们可以 推送 到镜像服务器,逆向可以 拉取 到上传的镜像,或者说我们可以保存为 压缩包 进行 相互传递 。 在本地的镜像可以传来传去,本身也可以查看

    2024年02月01日
    浏览(53)
  • 【无标题】如何使用Docker构建多平台镜像?

    如何构建多平台镜像? 工作原理 准备构建环境 开启Linux内核对多处理器架构的支持 创建使用\\\"docker-container\\\"驱动的Buildx实例 调整Dockerfile 调整构建命令 在不同镜像仓库之间传输镜像 如何构建多平台镜像? 如果你还不了解什么是多平台构建,请先阅读一下Docker构建多平台镜像

    2024年02月11日
    浏览(48)
  • libreOffice构建docker镜像,并基于此运行项目

    一、libreOffice构建docker镜像,并启动项目 安装包准备 LibreOffice(v7.4.2): LibreOffice_7.4.2_Linux_x86-64_rpm.tar.gz LibreOffice-langpack:(v7.4.2): LibreOffice_7.4.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz jdk-8u202-linux-x64.tar.gz 打包windows字体包(C:WindowsFonts,搜索中文):fonts.tar.gz Dockerfile编写 构建镜像 启动项

    2024年02月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包