docker多架构镜像构建

docker多架构镜像构建

Docker 多架构镜像构建(Multi-Architecture Image Build)允许你为不同平台(如 linux/amd64, linux/arm64, linux/arm/v7 等)构建和推送统一的镜像标签,解决在不同硬件架构之间部署的问题。

Docker 官方推荐使用 buildx 来构建多架构镜像。构建完了需要往harbor仓库进行推送

安装docker buildx

安装命令:

sh 复制代码
mkdir -p $HOME/.docker/cli-plugins
wget https://github.com/docker/buildx/releases/download/v0.12.0/buildx-v0.12.0.linux-amd64 -O $HOME/.docker/cli-plugins/docker-buildx
chmod +x $HOME/.docker/cli-plugins/docker-buildx

查看插件版本:

sh 复制代码
docker buildx version

查看当前系统中 Docker Buildx 支持使用的架构

sh 复制代码
docker buildx ls 

结果如下:可以看到默认是default,并且不支持arm架构

sh 复制代码
default * docker                                                        default         running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386

安装二进制文件格式解释器:

sh 复制代码
docker run --privileged --rm tonistiigi/binfmt --install all

此时再去查看架构支持:

sh 复制代码
[root@localhost ~]# docker buildx ls 
NAME/NODE DRIVER/ENDPOINT STATUS  BUILDKIT                              PLATFORMS
default * docker                                                        
  default default         running v0.11.7-0.20230525183624-798ad6b0ce9f 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

创建新的构建实例:

使用 docker-container 驱动程序创建一个新的构建器,它可以让您访问更复杂的功能,比如多平台构建和更高级的缓存导出功能。这些功能在默认的 docker 驱动程序中目前不受支持。

sh 复制代码
docker buildx create --name mybuilder --bootstrap --use

构建多架构镜像

编写Dockerfile:

sh 复制代码
FROM dockerpull.org/eclipse-temurin:8u392-b08-jdk-jammy

# 如果容器需要操作宿主机docker
RUN apt-get update && apt-get install -y libltdl7
  
# 将当前目录下的 java.security 文件复制到容器中指定路径
COPY java.security /opt/java/openjdk/jre/lib/security/java.security

使用 Buildx 插件构建镜像:

sh 复制代码
docker buildx build --platform=linux/arm64,linux/amd64 -t 192.168.51.52:8082/xxx/jdk8 --push .

遇到问题:

sh 复制代码
ERROR: failed to solve: failed to push 192.168.51.52:8082/xxx/jdk8: failed to do request: Head "https://192.168.51.52:8082/v2/xxx/jdk8/blobs/sha256:bb699589ec711474bb920a23601539265a47d38d3f6ca3e52cf61f5bf3143376": http: server gave HTTP response to HTTPS client

解决办法:https://github.com/docker/buildx/issues/163

新建一个配置文件buildkitd.toml

sh 复制代码
# 配置私有仓库
[registry."192.168.51.52:8082"]
  http = true
  insecure = true

# 配置 docker.io 的代理为 dockerpull.org
[registry."docker.io"]
  # mirrors = ["dockerpull.org"]
  http = false  # 如果 dockerpull.org 使用 HTTPS,请确保设为 false
  insecure = false  # 假设 dockerpull.org 使用 HTTPS

重新构建一个工具

sh 复制代码
docker buildx create --name mybuilder  --config ./buildkitd.toml --bootstrap --use

此时再去构建了往自己的私有仓库harbor推送:

sh 复制代码
docker buildx build --platform=linux/arm64,linux/amd64 -t 192.168.51.52:8082/xxx/jdk8 --push .

Docker多阶段构建

举个例子,我需要在eth-security-toolbox的基础上构建一个镜像,需要在这个镜像的基础上,装一个java,但是amd和arm架构的java需要的安装包是不同的,并且还需要对java源码里的部分内容做改造,所以需要将不同架构的java的安装包拷贝到容器里进行构建:

sh 复制代码
# 修改后(正确:使用目标平台架构)
FROM --platform=$TARGETPLATFORM docker.1ms.run/trailofbits/eth-security-toolbox:nightly-20241209 AS base

USER root
RUN solc-select install 0.8.19 && solc-select use 0.8.19
WORKDIR /opt

# ========== 平台感知最终阶段 ==========
FROM base AS final

ARG TARGETARCH
# docker buildx 会自动设置这个变量为 amd64 或 arm64

COPY jdk_amd64.tar.gz .
COPY jdk_arm64.tar.gz .

# 选择正确的包名
RUN set -eux; \
    if [ "$TARGETARCH" = "amd64" ]; then \
        tar -xzf jdk_amd64.tar.gz -C /opt && rm -f jdk_amd64.tar.gz jdk_arm64.tar.gz; \
    elif [ "$TARGETARCH" = "arm64" ]; then \
        tar -xzf jdk_arm64.tar.gz -C /opt && rm -f jdk_amd64.tar.gz jdk_arm64.tar.gz; \
    else \
        echo "Unsupported arch: $TARGETARCH" && exit 1; \
    fi

ENV JAVA_HOME=/opt/jdk8u392-b08
ENV PATH=$JAVA_HOME/bin:$PATH

# 可选测试(可注释)
# RUN java -version

构建脚本:

sh 复制代码
docker buildx build --platform=linux/arm64,linux/amd64 -t 192.168.51.52:8082/xxx/contract-base:latest --push --no-cache .
  • FROM --platform=$TARGETPLATFORM ... AS base :指定基础镜像的平台与目标平台一致。$TARGETPLATFORM 是 Docker Buildx 自动注入的变量,值为 linux/amd64linux/arm64 ,这里是为了确保基础镜像的架构与最终构建目标匹配,避免跨平台兼容问题。
  • ARG TARGETARCH :声明一个构建参数 TARGETARCH,其值由 Docker Buildx 自动注入。在多平台构建时,TARGETARCH 会根据 --platform 参数动态设置为 amd64arm64
  • **RUN set -eux; if [ "$TARGETARCH" = "amd64" ]; then ...**根据 TARGETARCH 的值动态选择解压对应的 JDK。

测试阶段:

测试构建后java是否可用,下面的命令可以分别在amd和arm机器上执行:

sh 复制代码
docker run --rm -it 192.168.51.52:8082/xxx/contract-base:test java -version

或者也可以进入构建后的容器:

sh 复制代码
docker run --rm -it --platform=linux/amd64 192.168.51.52:8082/xxx/contract-base:test /bin/bash

使用下面命令来判断是不是对应架构的,但是使用docker inspect images命令不准,还是进入容器比较好:

sh 复制代码
uname -m 

判断构建的镜像 manifest 是不是双架构的

sh 复制代码
docker buildx imagetools inspect 192.168.51.52:8082/xxx/contract-base:test

##参考文档

使用 Docker 构建多架构镜像

相关推荐
掘金安东尼10 分钟前
AI 应用落地谈起 ,免费试用 Amazon Bedrock 的最佳时机
java·架构
杨杨杨大侠27 分钟前
案例03-附件E-部署运维
java·docker·github
掘金安东尼1 小时前
Amazon Lambda + API Gateway 实战,无服务器架构入门
算法·架构
泉城老铁4 小时前
Spring Boot对接抖音获取H5直播链接详细指南
spring boot·后端·架构
Java陈序员4 小时前
直播录制神器!一款多平台直播流自动录制客户端!
python·docker·ffmpeg
水冗水孚5 小时前
你用过docker部署前端项目吗?Tell Me Why 为何要用docker部署前端项目呢?
ubuntu·docker·容器
飞询5 小时前
docker 部署 sftp
运维·docker
IT小番茄6 小时前
Docker Registry安全运维实战指南:从漏洞修复到高可用部署
架构
绝无仅有6 小时前
某辅导教育大厂真实面试过程与经验总结
后端·面试·架构
NAGNIP1 天前
Serverless 架构下的大模型框架落地实践
算法·架构