docker的神奇之处,目前大概也有了点初步的了解了,由于最近在处理跨平台构建镜像的问题,发现docker 在拉取镜像时,会自动根据当前机器的架构,拉取符合当前架构的镜像,这样保证了镜像拉下来之后可以正常运行。
这也是为什么有时候我们拉取别人构建的镜像,无法运行的问题。
如果镜像的架构和当前机器的架构不一致,则运行镜像的时候,容器会立马停掉,然后日志里面显示可恶的:standard_init_linux.go:228: exec user process caused: exec format error
所以构建镜像时,如果有不同平台可以测试,构建两份镜像,就可以完美的解决这个问题了。
下面以jdk8
镜像为例,创建一份多平台的镜像包。
这里不再叙述怎么打包的镜像了,只记录下如何将不同平台的镜像包提出来一个统一的入口,具体拉取哪个镜像,让机器自动匹配。其实也就是用到了docker的manifest
,关于manifest
的知识,可以看下这篇文章:Docker manifest 详解
docker manifest命令来制作多架构镜像,这个命令目前还是实验性质的,需要把docker的实验模式打开。我这里是20.20.5
版本的,已经打开了,忘记是不是自己手动打开的了,如果没有打开,手动配置下。
首先保证本地已经包含两个平台的镜像包了
这里可以看到,有两个镜像,分别是arm64和x86_64。还有一点需要保证的是:远程仓库里面也必须要有这两个镜像,否则下面创建 manifest
时,会提示:no such manifest: onlyonelmm/jdk8:x86_64
创建一个新的 manifest
,指定多架构镜像的名称,和具体的不同架构的镜像名称
docker manifest create --insecure onlyonelmm/jdk8:latest onlyonelmm/jdk8:x86_64 onlyonelmm/jdk8:arm64
声明不同架构镜像对应的操作系统和cpu架构类型,其中x86_64需要用amd64来指定
docker manifest annotate onlyonelmm/jdk8:latest onlyonelmm/jdk8:x86_64 --os linux --arch amd64
docker manifest annotate onlyonelmm/jdk8:latest onlyonelmm/jdk8:arm64 --os linux --arch arm64
将manifest推送到私用仓库中
docker manifest push --insecure onlyonelmm/jdk8:latest
由于这两个不同架构的镜像,已经存在我的docker hub里面了,上面在推送的时候,就没有显示上传了。
可以看到docker hub上面已经有了latest
版本,并且包含两个不同架构的镜像,其中镜像的ID分别是下面的两个不同架构的镜像的ID。
随便找一台x86_64
架构的机器测试拉取镜像:
可以看到正常拉下来了。然后看下镜像的架构是否一致。使用 docker inspect 镜像ID
再找一台 ARM架构服务器测试拉取镜像看下。
完美。
这里也可以将我们的镜像推送至私有仓库里面。方法是一样的,只需要保证镜像的名称符合镜像仓库规范即可。