Multi-Architecture镜像制作指南已到,请查收!
摘要:使用Multi-Architecture镜像,可以让docker根据系统架构去拉取对应的镜像,服务的部署脚本等可以在不同架构的系统间使用相同的配置,减化服务配置,提高了服务在不同系统架构间的一致性。
背景
由于Kubernetes集群支持amd64和arm64架构的系统,容器部署时两种类型的节点都可能被集群调度到;所以容器在打包推送到镜像仓库时需要考虑支持多架构,防止调度到不支持的架构节点导致运行失败。
简介
- Docker register: v2.3.0开始支持Multi-Architecture镜像
- Docker CLI
- v1.11开始支持Multi-Architecture镜像拉取
- v18.03开始支持Multi-Architecture镜像制作
参考资料:
- Manifest标准:https://docs.docker.com/registry/spec/manifest-v2-1/
- Manifest命令:https://docs.docker.com/engine/reference/commandline/manifest/
- Registry:https://github.com/docker/distribution/releases/tag/v2.3.0
制作说明
虽然Multi-Architecture标准很早就有,但是官方的Docker CLI直到v18.03版本才开始支持Multi-Architecture镜像的制作;或者可以考虑使用第三方工具,参考:构建多CPU架构支持的Docker镜像
后续Multi-Architecture镜像的制作使用Docker v18.09版本进行说明。
设置Docker
Docker使用manifest命令来设置MANIFEST_LIST从而支持Multi-Architecture。到Docker v18.09版本为止,manifest命令还是实验性的,所以要配置Docker使能实验性功能。
Docker daemon
修改配置文件/etc/docker/daemon.json,添加配置"experimental": true:
$ sudo cat /etc/docker/daemon.json
[sudo] password for zhangsan:
{
"data-root": "/home/common/docker",
"experimental": true, <- 使能docker daemon实验性功能
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-file": "10",
"max-size": "100m"
},
"insecure-registries": [
"docker-hub.***.com"
]
}
Docker Cli
修改当前用户home目录的配置文件~/.docker/config.json,添加配置"experimental": "enabled":
$ cat ~/.docker/config.json
{
"experimental": "enabled", <- 使能docker cli实验性功能
"proxies":
{
"default":
{
"httpProxy": "http://127.0.0.1:3128",
"httpsProxy": "http://127.0.0.1:3128",
"ftpProxy": "http://127.0.0.1:3128"
}
}
}
验证配置
重启docker服务,手工运行docker manifest,出现如下信息说明配置成功:
$ docker manifest Usage: docker manifest COMMAND Manage Docker image manifests and manifest lists Commands:
annotate Add additional information to a local image manifest
create Create a local manifest list for annotating and pushing to a registry
inspect Display an image manifest, or manifest list
push Push a manifest list to a repository Run 'docker manifest COMMAND --help' for more information on a command.
镜像打包
示例程序stop是一个go程序,启动后暂停不做任何操作,编译到amd64和arm64平台,在amd64平台分别运行如下:
$ ll -hR
.:
total 8.0K
drwxrwxr-x 2 zhangsan zhangsan 4.0K Jun 3 17:21 amd64
drwxrwxr-x 2 zhangsan zhangsan 4.0K Jun 3 17:21 arm64 ./amd64:
total 240K
-rw-rw-r-- 1 zhangsan zhangsan 51 Jun 3 17:21 Dockerfile
-rwxrwxr-x 1 zhangsan zhangsan 235K Jul 19 2014 stop ./arm64:
total 656K
-rw-rw-r-- 1 zhangsan zhangsan 51 Jun 3 17:21 Dockerfile
-rwxr-xr-x 1 zhangsan zhangsan 651K May 22 14:38 stop $ amd64/stop
^C% $ arm64/stop
zsh: exec format error: arm64/stop
使用相同的Dockerfile:
$ cat Dockerfile
FROM scratch COPY stop /stop
ENTRYPOINT ["/stop"]
amd64版本
$ cd amd64 $ ls
Dockerfile stop # 使用tag标注平台信息。
$ docker build -t docker-hub.***.com/zhangsan/stop:1.0-amd64 .
Sending build context to Docker daemon 242.7kB
Step 1/3 : FROM scratch
--->
Step 2/3 : COPY stop /stop
---> ffb0d366bb8c
Step 3/3 : ENTRYPOINT ["/stop"]
---> Running in 715d1fbcf450
Removing intermediate container 715d1fbcf450
---> 0584fe60ca3d
Successfully built 0584fe60ca3d
Successfully tagged docker-hub.***.com/zhangsan/stop:1.0-amd64 $ docker images | grep stop
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-hub.***.com/zhangsan/stop 1.0-amd64 0584fe60ca3d 3 seconds ago 240kB $ docker push docker-hub.***.com/zhangsan/stop:1.0-amd64
The push refers to repository [docker-hub.***.com/zhangsan/stop]
9e352dcc98ab: Pushed
1.0-amd64: digest: sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f size: 526 # 可以用manifest的子命令inspect查看镜像的manifest信息,由于是私有仓库,需要使用--insecure参数。
$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0-amd64
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",
"size": 526,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1489,
"digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 71322,
"digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"
}
]
}
}
arm64版本
$ cd arm64 $ ls
Dockerfile stop $ docker build -t docker-hub.***.com/zhangsan/stop:1.0-arm64 .
Sending build context to Docker daemon 669.2kB
Step 1/3 : FROM scratch
--->
Step 2/3 : COPY stop /stop
---> e02dd9cc9ffa
Step 3/3 : ENTRYPOINT ["/stop"]
---> Running in 9b574680691a
Removing intermediate container 9b574680691a
---> 1fc97e49b088
Successfully built 1fc97e49b088
Successfully tagged docker-hub.***.com/zhangsan/stop:1.0-arm64 $ docker images | grep stop
docker-hub.***.com/zhangsan/stop 1.0-arm64 1fc97e49b088 8 seconds ago 666kB
docker-hub.***.com/zhangsan/stop 1.0-amd64 0584fe60ca3d 3 minutes ago 240kB $ docker push docker-hub.***.com/zhangsan/stop:1.0-arm64
The push refers to repository [docker-hub.***.com/zhangsan/stop]
a0c07ccfc4ae: Pushed
1.0-arm64: digest: sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6 size: 527 # 由于打包镜像的机器是amd64架构,所以arm64的应用镜像中architecture为amd64,后面可以修改,或者直接在arm64机器上打包。
$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0-arm64
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",
"size": 527,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1488,
"digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 318698,
"digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"
}
]
}
}
验证镜像
$ docker images | grep stop
docker-hub.***.com/zhangsan/stop 1.0-arm64 1fc97e49b088 21 hours ago 666kB
docker-hub.***.com/zhangsan/stop 1.0-amd64 0584fe60ca3d 21 hours ago 240kB $ docker run docker-hub.***.com/zhangsan/stop:1.0-amd64
^C% $ docker run docker-hub.***.com/zhangsan/stop:1.0-arm64
standard_init_linux.go:207: exec user process caused "exec format error"
创建MANIFEST_LIST
创建一个MANIFEST_LIST引用之前两个不同平台的镜像。
$ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0
no such manifest: docker-hub.***.com/zhangsan/stop:1.0 $ docker manifest create --insecure docker-hub.***.com/zhangsan/stop:1.0 docker-hub.***.com/zhangsan/stop:1.0-amd64 docker-hub.***.com/zhangsan/stop:1.0-arm64
Created manifest list docker-hub.***.com/zhangsan/stop:1.0 $ docker manifest inspect -v --insecure docker-hub.***.com/zhangsan/stop:1.0
[
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",
"size": 526,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1489,
"digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 71322,
"digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"
}
]
}
},
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",
"size": 527,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1488,
"digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 318698,
"digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"
}
]
}
}
]
修改MANIFEST_LIST
修改刚创建的MANIFEST_LIST,使镜像和架构对应。
$ docker manifest annotate docker-hub.***.com/zhangsan/stop:1.0 docker-hub.***.com/zhangsan/stop:1.0-arm64 --arch arm64
[
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-amd64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e5b6263b7e45840f139f1bf40b774294712c95df1b43d41598b736f07110341f",
"size": 526,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1489,
"digest": "sha256:0584fe60ca3dbff4c746d376855e89b72b022a4198373b3c8d4c41b97b8b4faf"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 71322,
"digest": "sha256:7797d3b3ba41f7abc6a914250f793cf2d69a3e7c0bcc787a596eab4836554552"
}
]
}
},
{
"Ref": "docker-hub.***.com/zhangsan/stop:1.0-arm64",
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:089798dc96fcc3d2bf4da3ec4243adcc2507d2ae0c5ba77c5582af626702b3d6",
"size": 527,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1488,
"digest": "sha256:1fc97e49b0883f59e1e894404785ea1867b9e557d55bdac92f2da09c92b659e7"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 318698,
"digest": "sha256:4397808817371da0348eb097ca181996165a9836d629aa1fb97b0d3824ffe2e2"
}
]
}
}
]
推送MANIFEST_LIST到镜像仓库
创建的MANIFEST_LIST会保存在本地目录~/.docker/manifests,在push时可以使用-p(--purge)参数删除本地数据:
$ ll -R ~/.docker/manifests
/home/zhangsan/.docker/manifests:
total 4
drwxr-xr-x 2 zhangsan zhangsan 4096 Jun 3 17:57 docker-hub.***.com_zhangsan_stop-1.0 /home/zhangsan/.docker/manifests/docker-hub.***.com_zhangsan_stop-1.0:
total 8
-rw-r--r-- 1 zhangsan zhangsan 733 Jun 3 17:57 docker-hub.***.com_zhangsan_stop-1.0-amd64
-rw-r--r-- 1 zhangsan zhangsan 734 Jun 3 18:01 docker-hub.***.com_zhangsan_stop-1.0-arm64 $ sudo docker manifest push -p --insecure docker-hub.***.com/zhangsan/stop:1.0
[sudo] password for zhangsan:
sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400ece
验证
$ docker images | grep stop
docker-hub.***.com/zhangsan/stop 1.0-arm64 1fc97e49b088 16 hours ago 666kB
docker-hub.***.com/zhangsan/stop 1.0-amd64 0584fe60ca3d 16 hours ago 240kB # 在amd64架构的系统下拉取不带架构信息的镜像
$ uname -a
Linux SZX1000514415 4.4.0-87-generic #110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux $ docker pull docker-hub.***.com/zhangsan/stop:1.0
1.0: Pulling from zhangsan/stop
Digest: sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400ece
Status: Downloaded newer image for docker-hub.***.com/zhangsan/stop:1.0 $ docker images | grep stop
docker-hub.***.com/zhangsan/stop 1.0-arm64 1fc97e49b088 16 hours ago 666kB
docker-hub.***.com/zhangsan/stop 1.0 0584fe60ca3d 16 hours ago 240kB
docker-hub.***.com/zhangsan/stop 1.0-amd64 0584fe60ca3d 16 hours ago 240kB # 可正常运行
$ docker run docker-hub.***.com/zhangsan/stop:1.0
^C% # 在arm64架构的系统下拉取不带架构信息的镜像
[root@kwephicprc09532 ~]# uname -a
Linux kwephicprc09532 4.1.44-06.160.vhulk1711.1.1.aarch64 #1 SMP Tue Oct 16 18:45:06 UTC 2018 aarch64 aarch64 aarch64 GNU/Linux [root@kwephicprc09532 ~]# docker images | grep stop [root@kwephicprc09532 ~]# docker pull docker-hub.***.com/zhangsan/stop:1.0
1.0: Pulling from zhangsan/stop
439780881737: Pull complete
Digest: sha256:401767ef0864a65578bef86e3baed2e1e0be905d08d88b57cdeb299850400ece
Status: Downloaded newer image for docker-hub.***.com/zhangsan/stop:1.0 [root@kwephicprc09532 ~]# docker images | grep stop
docker-hub.***.com/zhangsan/stop 1.0 1fc97e49b088 16 hours ago 666.5 kB # 可正常运行
[root@kwephicprc09532 ~]# docker run docker-hub.***.com/zhangsan/stop:1.0
^CShutting down, got signal: Interrupt
升级MANIFEST_LIST
后期升级MANIFEST_LIST方法与创建类似,如:docker-hub.***.com/zhangsan/stop:1.0-amd64镜像升级或docker-hub.***.com/zhangsan/stop:1.0这个MANIFEST_LIST要关联其它镜像时,都需要升级MANIFEST_LIST。需要注意几点:
- manifest create时使用参数-a(--amend)
- 升级后没有关联到期望的镜像可以先手工删除本地保存的manifest再尝试
使用Multi-Architecture镜像的好处
使用Multi-Architecture镜像,可以让docker根据系统架构去拉取对应的镜像,服务的部署脚本等可以在不同架构的系统间使用相同的配置,减化服务配置,提高了服务在不同系统架构间的一致性。
本文分享自华为云社区《叮!快收好这份Multi-Architecture镜像制作指南》,原文作者:Thirteenmans 。
Multi-Architecture镜像制作指南已到,请查收!的更多相关文章
- OpenStack 镜像制作
Contents [hide] 1 Centos6.5 img制作 1.1 基础环境安装 1.2 下载或从本地上传系统镜像 1.3 启动服务 1.4 建立镜像文件 1.5 通过virt-install ...
- 测试环境docker化(一)—基于ndp部署模式的docker基础镜像制作
本文来自网易云社区 作者:孙婷婷 背景 我所在测试项目组目前的测试环境只有一套,在项目版本迭代过程中,开发或产品偶尔会在测试环境进行数据校验,QA人数在不断增加,各个人员在负责不同模块工作时也会产生脏 ...
- Docker系列-(2) 镜像制作与发布
上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布. 镜像文件结构 Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图 ...
- MySQL、MongoDB、Redis数据库Docker镜像制作
MySQL.MongoDB.Redis数据库Docker镜像制作 在多台主机上进行数据库部署时,如果使用传统的MySQL的交互式的安装方式将会重复很多遍.如果做成镜像,那么我们只需要make once ...
- 自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版
MSDN官网上下载的Windows7 64位 旗舰版原版镜像制作,绝对纯净版,无任何精简,不捆绑任何第三方软件.浏览器插件,不含任何木马.病毒等. 集成: 1.Office2010 2.DirectX ...
- 初涉定制linux系统之——自动化安装Centos系统镜像制作
最近碰到个需求:要在内网环境安装centos6.5系统并搭建服务,但由于自动部署脚本里安装依赖包使用的是yum安装,而服务器无法连接外网,实施人员也不会本地yum源搭建O__O "….. 本 ...
- openStack镜像制作
参考链接: https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/OpenStack/page/Creating ...
- OpenStack镜像制作-CentOS
云平台中镜像还是很重要的,提供各种定制化的镜像使得用户体验更好. 最开始玩OpenStack的时候用的是安装文档中提到的cirros,其密码cubswin:) 刚开始感觉很怪,现在已经可以随手打出.p ...
- openstack私有云布署实践【16.1 CentOS7.1 只有根分区镜像制作】
之所以要只有根分区镜像,是因为在创建VM或者调整云主机的硬盘大小时,它能自动扩容.无需人工介入 在原来的物理机10.40.41.1的CentOS 6.7上制作镜像.(当然如果你的制作镜像的宿主机是 ...
- #openstack centos6 centos7 kvm镜像制作
#openstack centos6 centos7 kvm 镜像制作 openstack windows 2008镜像 制作 http://www.cnblogs.com/elvi/p/800129 ...
随机推荐
- .NET高性能开发-位图索引(一)
首先来假设这样一个业务场景,大家对于飞机票应该不陌生,大家在购买机票时,首先是选择您期望的起抵城市和时间,然后选择舱等(公务舱.经济舱),点击查询以后就会出现航班列表,随意的点击一个航班,可以发现有非 ...
- 虹科干货 | 什么是Redis数据集成(RDI)?
大量的应用程序.日益增长的用户规模.不断扩展的技术需求,以及对即时响应的持续追求.想想这些是否正是你在经历的.也许你尝试过自己构建工具来应对这些需求,但是大量的编码和集成工作使你焦头烂额.那你是否知道 ...
- shell脚本之规范与变量
shell编程规范与变量 名词简述 面向过程语言 按照顺序执行程序 第一件事干什么->第二件事干什么......(C,shell...) 面向对象语言 把程序看成一个整体(java,python ...
- 提升运维效率:轻松掌握JumpServer安装和使用技巧
前言 JumpServer 是一个开源的跳板机的解决方案,提供了对远程服务器的安全访问.会话录制和审计.用户身份管理等功能,适用于需要管理机器资源&大量服务器资源的情况. 本文将在分享 doc ...
- 从一道题来看看golang中的slice作为参数时的现象
1.题目 最近看群友在群里问一道关于golang中slice的题,题目如下: package main import "fmt" func main() { k := []int{ ...
- go 上下文:context.Context
Go语言中的上下文(Context)是一种用于在 Goroutines 之间传递取消信号.截止时间和其他请求范围值的标准方式.context 包提供了 Context 类型和一些相关的函数,用于在并发 ...
- 轻松一刻|Walrus CLI与CI/CD工具集成,轻松部署2048游戏
Walrus 是一款开源的基于平台工程理念.以应用为中心.以完整应用系统自动化编排交付为目标进行设计开发的云原生应用平台,简化和自动化应用部署与发布流程并与现有的 CI/CD 流水线无缝集成.今天我们 ...
- 如何在langchain中对大模型的输出进行格式化
简介 我们知道在大语言模型中, 不管模型的能力有多强大,他的输入和输出基本上都是文本格式的,文本格式的输入输出虽然对人来说非常的友好,但是如果我们想要进行一些结构化处理的话还是会有一点点的不方便. 不 ...
- Pattern类和Matcher类的使用
1.先看好数据源 先将一个String对象确定为程序要对其进行操作的数据源. String b="hello,good morning"; 2.建立Pattern类的对象 Stri ...
- Vue入门(1)安装vue环境,创建Vue2 Vue3的项目并且安装IIS环境和发布到IIS
Vue环境的搭建 一. 背景 vue的运行方式有两种 一种是在页面引用vue的js包, 一种是搭建脚手架来vue框架. 我们在这里使用的是第二种方式. 需要安装的软件 npm 16.13.1 ...