如何构建多架构(Multi-Arch)的容器镜像(一)

    Docker的目标是 “Build, Ship, and Run Any App, Anywhere” 。但是我们在实际环境中会发现现在的服务器除了Intel x86架构的还有ARM,也有OpenPOWER(ppc64le).Docker Image是容器运行的基础,它是依赖于操作系统的。比如说我们不能把一个tomcat的ppc64le/linux架构的Docker镜像运行在amd64/linux 架构的环境中,否则你会遇到 “exec format error”。早期Docker镜像存储的设计没有充分考虑到镜像Multi architecture的支持,而是简单的使用镜像存储库的前缀来区分相同应用的不同平台,并建议开发者将不同平台的镜像应该push到相对应的Docker hub的镜像仓库中。

    从Docker registry v2.3和Docker 1.10 开始,Docker hub就可以pull multi architecture Docker镜像了.Docker社区重新定义了 v2.2 Image specification format(PR #1068)并在 Implement schema2 manifest formats(PR #1281)实现了Multi architecture Docker镜像功能。这个功能能够让我们在不同CPU架构的主机上,运行相同的docker pull 命令就可以直接获得符合当前主机CPU架构的镜像。比如在不同CPU架构的主机上运行 docker run -it --rm busybox arch 这个命令,我们能自动获取到不同架构的busybox的docker 镜像。除了busybox镜像,httpd,nginx, tomcat和etcd等主流开源应用都有了Multi architecture Docker镜像支持。在Docker Hub里只要镜像有显示支持不同架构的标签就是Multi architecture Docker镜像。

    Docker 通过使用 manifest lists 技术来实现Multi architecture Docker镜像。什么是image manifest list呢?一个image manifest list 包含指向已经存在镜像的manifest对象列表(图一)。

如何构建多架构(Multi-Arch)的容器镜像(一)_第1张图片

图一

一个image manifest list包含已经存在镜像的manifest对象的平台特性(CPU arch和OS类型)特征(图二)

如何构建多架构(Multi-Arch)的容器镜像(一)_第2张图片

图二

当我们运行docker pull拉取镜像的时候,如果registry响应 docker pull 命令不是 image manifest里的, Docker 检查manifest list 然后 pull该平台对应的 list entry然后再运行。distribution protocol 是后向兼容的,  manifest lists 只服务于指明了支持 Accept header的客户端。对于不支持 manifest lists的客户端, registries 将会返回给 x86-64 Linux image manifest. Manifest lists 通过 Docker Content Trust 支持全部特征,确保 multi-platform image 内容被加密验证和检验。

     制作一个multi architecture Docker镜像最重要的是定义image的manifest list。下面演示分别使用两种工具定义manifest list

1 . Enhanced Docker CLI

这是加强版的Docker CLI,他的code base 是基于社区的Docker CLI,并且marge了 Docker官方的Add manifest command这个pull request,它很好的集成了现有的Docker CLI, 并且增加了docker manifest的sub command 支持。

a. 构建myapp的x86_64镜像,并且push到Docker hub上

docker build -t huxl/myapp-x86_64:v1

b. 构建myapp的ppc64le镜像,并且push到Docker hub上

docker build -t huxl/myapp-ppc64le:v1

c. 创建指向myappp的x86_64和ppc64le的镜像的manifests list对象并将它push到docker hub

./docker manifest create huxl/myapp:v1 huxl/myapp-x86_64:v1 huxl/myapp-ppc64le:v1

./docker manifest annotate huxl/myapp:v1 huxl/myapp-x86_64:v1 --os linux --arch amd64

./docker manifest annotate huxl/myapp:v1 huxl/myapp-ppc64le:v1 --os linux --arch ppc64le

./docker manifest push huxl/myapp:v1

2. Manifest-tool

这是一个独立的小工具,它也实现了v2.2 Image specification format,并且支持查看,创建和push manifests list 对象到Docker registry,并且更加方便易用,因为它可以使用yaml文件定义image manifest list对象。

a. 创建一个yaml文件用来表述支持multi architecture的镜像myapp:v1

         image: huxl/myapp:v1

              manifests:

                  image: huxl/myapp-ppc64le:v1

                   platform:

                       architecture: ppc64le

                         os: linux

                    image: huxl/myapp-x86_64:v1

                    platform:

                        architecture: amd64

                        os: linux

b. push myapp.yaml到docker hub

./manifest-tool push from-spec myapp.yaml

Note:我们可以使用命令docker manifest inspect huxl/myapp:v1 或者 manifest-tool inspect huxl/mycool-app:v1看到这个multi architecture Docker镜像的manifest list,这里就不在赘述了。

总结

1Push multi architecture Docker镜像到Docker registry并不会push image的layers,它只会push一个引用,这个引用指向了已经存在的多个Docker镜像;

2只有multi architecture Docker镜像的创建者才需要知道这个引用背后指向具体的Docker镜像,而对最终的用户是透明的,最终用户只需要知道镜像的名字和tag就足够了;

3有了multi architecture Docker镜像支持,我们再也不用在脚本里面判断OS的类型和CPU的arch而去pull相应的镜像,提高CICD代码的简洁和优雅;

4Image manifest list是极好的兼容性设计,它不但支持multi architecture Docker镜像,而且不会影响已经在的simple architecture Docker镜像的使用方式, 用户不用做二选一的艰难的决定。

参考 

https://blog.csdn.net/dev_csdn/article/details/79138424

你可能感兴趣的:(如何构建多架构(Multi-Arch)的容器镜像(一))