先把当时的情况摆出来。腾讯云 CVM 是 x86_64 架构,Ubuntu 20.04 配 Docker 20.10,从 M1 笔记本上构建的镜像推到 Harbor 再拉到这台机器,docker run 立刻退出,docker logs 只有 standard_init_linux.go:228: exec user process caused: exec format error,加 --platform linux/amd64 还是原样。
真正麻烦的地方在于,几个原因的现象几乎一样。构建时只打了 linux/arm64 平台,manifest 里没有 amd64 条目。还有一种是打包那台笔记本默认架构是 arm64,docker build 直接沿用了本机架构。
少数情况下是基础镜像本身只有 arm64 版本,多架构清单里缺 x86 的层。不容易想到的是,推送时用单架构 tag 覆盖了原来的多架构 manifest。
上来先看镜像清单里到底有哪些平台
docker manifest inspect harbor.local/app:v3 | grep -A2 platform
随后在 amd64 机器上指定平台重新构建
docker buildx build --platform linux/amd64 -t harbor.local/app:v3 --push .
需要两边都跑就一次构建双架构
docker buildx build --platform linux/amd64,linux/arm64 -t harbor.local/app:v3 --push .
拉下来确认镜像架构和二进制格式
docker run --rm --entrypoint uname harbor.local/app:v3 -m
恢复的判定其实很直接。docker inspect 里 Architecture 显示 amd64,容器启动后日志正常,file 查二进制是 ELF 64-bit x86-64。
容易忽略的是,多架构 tag 很容易被一次单平台构建覆盖,CI 里应固定 --platform 并在推送后校验 manifest,别等上线才发现。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
