M1芯片Mac构建的Java应用Docker镜像在K8s运行报exec format错误
问题根因
你遇到的exec format error是典型的CPU架构不兼容问题:搭载M1芯片的Mac是arm64/aarch64架构,默认构建的Docker镜像适配arm64架构,而你的Kubernetes集群服务器是x86_64/amd64架构,两种架构的二进制执行文件不通用,所以启动时报错,你之前修改Entrypoint、CMD的操作和该报错没有关联,自然不会生效。
可行解决方案
方案1:构建时指定目标架构(最常用,无需额外环境)
Docker Desktop for M1内置了buildx多架构构建能力,直接在构建命令中指定目标架构为amd64即可:
- 单独用docker命令构建执行如下指令:
docker buildx build --platform linux/amd64 -t my.private.repo/app_dir/myapp:1.0.3 -f myapp/Dockerfile .
- 如果用docker-compose构建,修改docker-compose.yaml的build配置,新增platform参数:
version: "3.8" services: myapp: build: context: . dockerfile: myapp/Dockerfile platforms: - "linux/amd64" hostname: myapphost platform: linux/amd64
构建完成后正常推送到私有镜像仓库,重新部署到K8s即可正常运行。
方案2:指定基础镜像的amd64版本
如果不想用buildx工具,也可以直接在Dockerfile中强制拉取对应amd64架构的基础镜像,修改第一行的FROM语句即可:
FROM --platform=linux/amd64 openjdk:11-jre-slim as jdkbase FROM jdkbase COPY app/target/dependency-jars /run/dependency-jars COPY app/target/resources /run/resources ADD app/target/app-1.0.3.jar /run/app-1.0.3.jar CMD java -jar run/app-1.0.3.jar
该方式会强制拉取amd64架构的JRE基础镜像,后续构建出的镜像默认就是amd64架构,可直接在x86的K8s集群运行。
方案3:在x86环境构建镜像
如果有可用的x86服务器或者CI/CD环境(绝大多数公共CI/CD资源都是x86架构),直接在对应环境拉取代码执行镜像构建,构建出的镜像天然适配x86架构,不会出现兼容性问题。
内容的提问来源于stack exchange,提问作者Victoria Agafonova
相关产品推荐
相关产品推荐

