容器化是一个私有云部署中比较流行的方式,把产品的各个模块打成docker镜像,通过swarm, rancher或者k8s等架构完成整体的部署。但是存在一个问题,私有云环境中存在x86,arm等不同的架构,所以在制作镜像过程中需要根据架构拉取正确的基础镜像。从docker hub上拉取镜像的时候会注意到在x86上拉取下来的就是x86的镜像,在arm环境上拉取的就一定是arm的镜像,这个功能简单来说就是docker的多架构镜像技术,网上的讲解很多不再赘述,这里具体讲一下怎么制作一个多架构镜像。
产品发布大概上是"从git拉取代码" -> "构建模块镜像" -> "发布到私有仓库" -> "从私有仓库拉取各模块镜像" -> "生成发布包" 这么个流程,所以为了能够生成不同架构的发布包,在"构建模块镜像"步骤中,需要使用不同架构的构建机器来构建出不同架构的"镜像"。
假如模块名称是"foo",私有仓库的地址是"docker.artifactory.xxx.com",最终需要支持x86_64和arm64两种环境,有两套构建环境A(x86_64)和B(arm64)。
首先在A上构建镜像docker.artifactory.xxx.com/foo:latest,并且发布到私有仓库,镜像名称中加上架构名称,
# 构建
docker build -t docker.artifactory.xxx.com/foo-x86_64:latest .
# 发布,如果私有仓库需要认证,则先通过docker login登录。
docker push docker.artifactory.xxx.com/foo-x86_64:latest
然后在B上重复这个过程,注意名称的不一样,
# 构建
docker build -t docker.artifactory.xxx.com/foo-arm64:latest .
# 发布,如果私有仓库需要认证,则先通过docker login登录。
docker push docker.artifactory.xxx.com/foo-arm64:latest
此时仓库上可以看到服务于两个不同架构的镜像。
然后,我们利用docker manifest命令来制作多架构镜像,这个命令目前还是实验性质的,所以需要把docker的实验模式打开。编辑~/.docker/config.json文件,加入如下配置,(以下步骤可以在任意能够访问到私有仓库的机器上执行,不限于构建机器)
[root@arm-build scripts]# cat ~/.docker/config.json
{ "experimental": "enabled" }
执行docker version查看是否修改成功,
[root@arm-build scripts]# docker version Client: Docker Engine - Community Version: 19.03.5 API version: 1.40 Go version: go1.12.12 Git commit: 633a0ea Built: Wed Nov 13 07:27:52 2019 OS/Arch: linux/arm64 Experimental: true <-表示实验模式已经打开
执行以下命令创建多架构镜像,--insecure指令可以忽略https证书的检查,
# 创建一个新的manifest,指定多架构镜像的名称,和具体的不同架构的镜像名称
docker manifest create --insecure docker.artifactory.xxx.com/foo:latest docker.artifactory.xxx.com/foo-x86_64:latest docker.artifactory.xxx.com/foo-arm64:latest
# 声明不同架构镜像对应的操作系统和cpu架构类型,其中x86_64需要用amd64来指定
docker manifest annotate docker.artifactory.xxx.com/foo:latest docker.artifactory.xxx.com/foo-x86_64:latest --os linux --arch amd64
docker manifest annotate docker.artifactory.xxx.com/foo:latest docker.artifactory.xxx.com/foo-arm64:latest --os linux --arch arm64
# 将manifest推送到私用仓库中
docker manifest push --insecure docker.artifactory.xxx.com/foo:latest
完成之后边可以通过docker.artifactory.xxx.com/foo:latest来在不同的架构环境里面拉取正确的镜像了。
通过这几条命令可以看出来多架构镜像只是一个引用,根据客户端的架构来选择其中声明好的镜像。so easy~