Docker 在 M1 Mac arm64架构上构建 amd64镜像。

Posted 额 无语

tags:

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

问题描述:通过在Mac M1电脑上构建的镜像,在linux x86的服务器上运行不起来,因为编译原理不一样。

构建好的镜像ID,通过docker inspect命令可以查看镜像的架构;

如下,同样的服务,构建出来的镜像架构确实不一样的。

[root@one-01 ~]# docker inspect 150b12879d3b | grep Architecture
        "Architecture": "arm64",
[root@one-01 ~]# 
[root@one-01 ~]# docker inspect 3ca177c70621 | grep Architecture
        "Architecture": "amd64",
[root@one-01 ~]# 

构建arm64使用的Dockerdile

FROM openjdk:8
RUN apt install tzdata && 
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ARG NAME
ARG FILE_URL

ENV APP_NAME=$NAME
ENV PROFILE=ca
ENV PORT=8080

ADD $FILE_URL app.jar


ENTRYPOINT java -jar -Dspring.profiles.active=$PROFILE -Dserver.port=$PORT -Duser.timezone=Asia/Shanghai /app.jar

构建amd64使用的镜像

FROM anapsix/alpine-java:8_server-jre_unlimited

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime


ARG NAME
ARG FILE_URL

ENV APP_NAME=$NAME
ENV PROFILE=caiicloud
ENV PORT=8080

ADD $FILE_URL app.jar

ENTRYPOINT java -jar -Dspring.profiles.active=$PROFILE -Dserver.port=$PORT -Duser.timezone=Asia/Shanghai /app.jar

分析一下可能是因为Dockerfile.

如果你也是Java镜像可以按照我的方式替换一下源镜像文件,如果是其他镜像,可以找一下适配amd64的源镜像文件。

我重新使用amd64的dockerfile构建了一下,查看到一个warning

—> [Warning] The requested image’s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

意思就是,请求的镜像是amd64的,在arm64上面构建不适配,但也是可以构建成功的。

运行的时候需要加一个–platform linux/amd64参数

下面是Docker官网的解释

另外Docker通过buildx.集成了Moby BuildKit工具包的 CLI 插件。这允许您为各种不同的 CPU 架构构建 Docker 映像,并且它在后台使用 QEMU 进行仿真。

可以通过命令查看支持的编译类型

docker buildx ls

相关链接推荐:How to build x86 (and others!) Docker images on an M1 Mac – Jaimyn’s Blog

最后

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。

ARM64架构下,OpenJDK的官方Docker镜像为何没有8版本

为什么需要ARM64架构的OpenJDK8的Docker镜像

对现有的Java应用,之前一直运行在x86处理器环境下,编译和运行都是JDK8,如今在树莓派的Docker环境运行(也可能是其他ARM环境,如华为的泰山ARM服务器),需要JDK8镜像作为基础镜像。

OpenJDK的官方Dockerfile

去OpenJDK的docker镜像官网查找找,地址是:https://hub.docker.com/r/arm64v8/openjdk ,如下图,只有JDK11的镜像:
技术图片

为啥没有OpenJDK8的镜像

心中略有不甘,想搞清楚为何没有,来探索一下;

  1. 打开OpenJDK8的官方GitHub,去看镜像的制作脚本Dockerfile的源码,地址是:https://github.com/docker-library/openjdk/blob/master/8/jdk/Dockerfile ,注意下图的内容:
    技术图片
  2. 从上图的分析我们了解到OpenJDK8镜像制作过程:先获取当前宿主机的处理器架构,执行命令是$(dpkg --print-architecture),在树莓派上执行此命令试试,如下,可见得到了$(dpkg --print-architecture)
root@raspbian:~# echo $(dpkg --print-architecture)
arm64
  1. 看上图红框3中的代码,如果处理器架构是arm64,那么变量upstreamArch就等于aarch64
  2. 看上图红框4中的代码,下载OpenJDK包的地址是${JAVA_BASE_URL}${upstreamArch}linux${JAVA_URL_VERSION}.tar.gz,这里面JAVA_BASE_URL、upstreamArch、JAVA_URL_VERSION的值都已经确定了,于是真实的地址就是:
https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u222-b10/OpenJDK8U-jdk_aarch64_linux_8u222b10.tar.gz
  1. 在浏览器输入上述地址试试,发现浏览器返回的是404错误,也就是说此地址无效;
  2. 将上述地址中的aarch64替换成x64,看看X86处理机架构下有没有OpenJDK8的下载包,新地址是:https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u222-b10/OpenJDK8U-jdk_x64_linux_8u222b10.tar.gz ,此地址可以顺利下载;
  3. 来看看OpenJDK官方为JDK8版本提供了哪些下载包,地址是:https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases ,如下图,清一色的x86架构:
    技术图片

结论

OpenJDK官方镜像的制作原理,是依据宿主机CPU架构去官方下载对应的OpenJDK安装包,再做成镜像,目前OpenJKD8的安装包并没有提供ARM版本,因此官方没有提供ARM版本的OpenJDK8的Docker镜像;

解决之道

现状是OpenJDK官方在ARM64架构不提供8版本的官方Docker镜像,解决此问题的思路有两个(个人观点,欢迎探讨)

  1. 自己编译一个8版本的OpenJDK安装包,以此来做Docker镜像;
  2. Oracle提供了ARM版本的JDKD安装包,以此包来做Docker镜像;
  3. 用OpenJDK的11版本,但是11和8的差异要自行处理;

对于第一种方式,自己编译8版本的OpenJDK,难度太大(对我自己而言),因为编译OpenJDK需要低版本的OpenJDK作为编译工具,也就是说我要找到ARM版本的OpenJDK7,才能编译ARM版本的OpenJDK8,因此我觉得这样做的难度太大...

对于第二种和第三种,后续的章节我们一起来实战吧;

欢迎关注公众号:程序员欣宸

以上是关于Docker 在 M1 Mac arm64架构上构建 amd64镜像。的主要内容,如果未能解决你的问题,请参考以下文章

记录MacOS M1芯片(ARM64架构)使用docker-compose方式部署Kafka

Mac m1 Ubuntu里docker中安装mysql

MAC M1下 docker部署Mysql和Navicate连接docker数据库

MAC M1下 docker部署Mysql和Navicate连接docker数据库

MAC M1下 docker部署Mysql和Navicate连接docker数据库

MAC M1下 docker部署Mysql和Navicate连接docker数据库