如何构建多种系统架构支持的 Docker 镜像
- 1.概述
- 2.解决方案
- 3.使用manifest案例
1.概述
我们知道使用镜像创建一个容器,该镜像必须与 Docker 宿主机系统架构一致,例如 Linux x86_64 架构的系统中只能使用 Linux x86_64 的镜像创建容器
例如我们在 Linux x86_64 中构建一个 username/test 镜像
FROM alpine
CMD echo 1
构建镜像后推送到 Docker Hub,之后我们尝试在树莓派 Linux arm64v8 中使用这个镜像
docker run -it --rm username/test
可以发现这个镜像根本获取不到
2.解决方案
以 golang:alpine
官方镜像为例,它有一个 manifest 列表 (manifest list)
当用户获取一个镜像时,Docker 引擎会首先查找该镜像是否有 manifest 列表,如果有的话 Docker 引擎会按照 Docker 运行环境(系统及架构)查找出对应镜像(例如 golang:alpine)。如果没有的话会直接获取镜像
我们可以使用 docker manifest inspect golang:alpine
查看这个 manifest 列表的结构:
可以看出 manifest 列表中包含了不同系统架构所对应的镜像 digest 值,这样 Docker 就可以在不同的架构中使用相同的 manifest (例如 golang:alpine) 获取对应的镜像
3.使用manifest案例
1、首先在 Linux x86_64 构建 username/x8664-test 镜像。并在 Linux arm64v8 中构建 username/arm64v8-test 镜像,构建好之后推送到 Docker Hub
2、创建 manifest 列表
docker manifest create username/test \
username/x8664-test \
username/arm64v8-test
3、设置 manifest 列表
docker manifest annotate username/test \
username/x8664-test \
--os linux --arch x86_64
docker manifest annotate username/test \
username/arm64v8-test \
--os linux --arch arm64 --variant v8
4、查看验证 manifest 列表
docker manifest inspect username/test
5、推送 manifest 列表
docker manifest push username/test
6、测试
我们在 Linux x86_64 Linux arm64v8 中分别执行 $ docker run -it --rm username/test 命令,发现可以正确的执行