- Docker 简介
- 什么是 Docker
- 为什么要用 Docker
- 基本概念
- 镜像
- 容器
- 仓库
- 安装 Docker
- Ubuntu
- Debian
- Fedora
- CentOS
- Raspberry Pi
- macOS 安装 Docker Desktop CE
- Windows 10
- 镜像加速器
- 使用镜像
- 获取镜像
- 列出镜像
- 删除本地镜像
- 利用 commit 理解镜像构成
- 使用 Dockerfile 定制镜像
- Dockerfile 指令详解
- COPY 复制文件
- ADD 更高级的复制文件
- CMD 容器启动命令
- ENTRYPOINT 入口点
- ENV 设置环境变量
- ARG 构建参数
- VOLUME 定义匿名卷
- EXPOSE 暴露端口
- WORKDIR 指定工作目录
- USER 指定当前用户
- HEALTHCHECK 健康检查
- ONBUILD 为他人作嫁衣裳
- 参考文档
- Dockerfile 多阶段构建
- 实战多阶段构建 Laravel 镜像
- 构建多种系统架构支持的 Docker 镜像
- 使用 buildx 构建多种系统架构支持的 Docker 镜像
- Docker v18.09 版本使用 BuildKit 构建镜像
- Docker v19.03 版本使用 BuildKit 构建镜像
- 其它制作镜像的方式
- 实现原理
- 操作容器
- 启动
- 守护态运行
- 终止
- 进入容器
- 导出和导入
- 删除
- 访问仓库
- Docker Hub
- 私有仓库
- 私有仓库高级配置
- Nexus 3
- 数据管理
- 数据卷
- 挂载主机目录
- 使用网络
- 外部访问容器
- 容器互联
- 配置 DNS
- 高级网络配置
- 快速配置指南
- 容器访问控制
- 端口映射实现
- 配置 docker0 网桥
- 自定义网桥
- 工具和示例
- 编辑网络配置文件
- 实例:创建一个点到点连接
- Docker Compose
- 简介
- 安装与卸载
- 使用
- 命令说明
- Compose 模板文件
- 实战 Django
- 实战 Rails
- 实战 WordPress
- Swarm mode
- 基本概念
- 创建 Swarm 集群
- 部署服务
- 使用 compose 文件
- 管理密钥
- 管理配置信息
- 滚动升级
- 安全
- 内核命名空间
- 控制组
- 服务端防护
- 内核能力机制
- 其它安全特性
- 总结
- 底层实现
- 基本架构
- 命名空间
- 控制组
- 联合文件系统
- 容器格式
- 网络
- Etcd 项目
- 简介
- 安装
- 集群
- 使用 etcdctl
- CoreOS 项目
- 简介
- 工具
- Kubernetes 项目
- 简介
- 快速上手
- 基本概念
- kubectl 使用
- 架构设计
- 容器与云计算
- 简介
- 亚马逊云
- 腾讯云
- 阿里云
- 小结
- 实战案例-操作系统
- Busybox
- Alpine
- Debian Ubuntu
- CentOS Fedora
- 本章小结
- 实战案例-CI/CD
- GitHub Actions
- Drone
- 部署 Drone
- Travis CI
- Docker 开源项目
- LinuxKit
- 附录
- 附录一:常见问题总结
- 附录二:热门镜像介绍
- Ubuntu
- CentOS
- Nginx
- PHP
- Node.js
- MySQL
- WordPress
- MongoDB
- Redis
- 附录三:Docker 命令查询
- 附录四:Dockerfile 最佳实践
- 附录五:如何调试 Docker
- 附录六:资源链接
- 归档
- Mesos - 优秀的集群资源调度平台
- Mesos 简介
- 安装与使用
- 原理与架构
- Mesos 配置项解析
- 日志与监控
- 常见应用框架
- 本章小结
- Docker Machine
- 安装
- 使用
- Docker Swarm
构建多种系统架构支持的 Docker 镜像
构建多种系统架构支持的 Docker 镜像 -- docker manifest 命令详解
我们知道使用镜像创建一个容器,该镜像必须与 Docker 宿主机系统架构一致,例如 Linux x86_64
架构的系统中只能使用 Linux x86_64
的镜像创建容器。
Windows、macOS 除外,其使用了 binfmt_misc 提供了多种架构支持,在 Windows、macOS 系统上 (x86_64) 可以运行 arm 等其他架构的镜像。
例如我们在 Linux x86_64
中构建一个 username/test
镜像。
FROM alpineCMD echo 1
构建镜像后推送到 Docker Hub,之后我们尝试在树莓派 Linux arm64v8
中使用这个镜像。
$ docker run -it --rm username/test
可以发现这个镜像根本获取不到。
要解决这个问题,通常采用的做法是通过镜像名区分不同系统架构的镜像,例如在 Linux x86_64
和 Linux arm64v8
分别构建 username/test
和 username/arm64v8-test
镜像。运行时使用对应架构的镜像即可。
这样做显得很繁琐,那么有没有一种方法让 Docker 引擎根据系统架构自动拉取对应的镜像呢?
我们发现在 Linux x86_64
和 Linux arm64v8
架构的计算机中执行 $ docker run golang:alpine go version
时我们发现可以正确的运行。
这是什么原因呢?
原因就是 golang:alpine
官方镜像有一个 manifest
列表。
当用户获取一个镜像时,Docker 引擎会首先查找该镜像是否有 manifest
列表,如果有的话 Docker 引擎会按照 Docker 运行环境(系统及架构)查找出对应镜像(例如 golang:alpine
)。如果没有的话会直接获取镜像(例如上例中我们构建的 username/test
)。
我们可以使用 $ docker manifest inspect golang:alpine
查看这个 manifest
列表的结构。
由于该命令属于实验特性,必须设置如下 环境变量 之后才能使用:
# Linux、macOS$ export DOCKER_CLI_EXPERIMENTAL=enabled# Windows$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled
以上是设置环境变量的临时方法,若使环境变量永久生效请读者自行设置。
设置之后,执行结果如下
$ docker manifest inspect golang:alpine
{ "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:5e28ac423243b187f464d635bcfe1e909f4a31c6c8bce51d0db0a1062bec9e16", "platform": { "architecture": "amd64", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:2945c46e26c9787da884b4065d1de64cf93a3b81ead1b949843dda1fcd458bae", "platform": { "architecture": "arm", "os": "linux", "variant": "v7" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:87fff60114fd3402d0c1a7ddf1eea1ded658f171749b57dc782fd33ee2d47b2d", "platform": { "architecture": "arm64", "os": "linux", "variant": "v8" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:607b43f1d91144f82a9433764e85eb3ccf83f73569552a49bc9788c31b4338de", "platform": { "architecture": "386", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:25ead0e21ed5e246ce31e274b98c09aaf548606788ef28eaf375dc8525064314", "platform": { "architecture": "ppc64le", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 1365, "digest": "sha256:69f5907fa93ea591175b2c688673775378ed861eeb687776669a48692bb9754d", "platform": { "architecture": "s390x", "os": "linux" } } ]}
可以看出 manifest
列表中包含了不同系统架构所对应的镜像 digest
值,这样 Docker 就可以在不同的架构中使用相同的 manifest
(例如 golang:alpine
) 获取对应的镜像。
下面介绍如何使用 $ docker manifest
命令创建并推送 manifest
列表到 Docker Hub。
构建镜像
首先在 Linux x86_64
构建 username/x8664-test
镜像。并在 Linux arm64v8
中构建 username/arm64v8-test
镜像,构建好之后推送到 Docker Hub。
创建 manifest
列表
# $ docker manifest create MANIFEST_LIST MANIFEST [MANIFEST...]$ docker manifest create username/test \ username/x8664-test \ username/arm64v8-test
当要修改一个 manifest
列表时,可以加入 -a,--amend
参数。
设置 manifest
列表
# $ docker manifest annotate [OPTIONS] MANIFEST_LIST 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
这样就配置好了 manifest
列表。
查看 manifest
列表
$ docker manifest inspect username/test
推送 manifest
列表
最后我们可以将其推送到 Docker Hub。
$ docker manifest push username/test
测试
我们在 Linux x86_64
Linux arm64v8
中分别执行 $ docker run -it --rm username/test
命令,发现可以正确的执行。
官方博客
详细了解 manifest
可以阅读官方博客。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论