阅读更多

0顶
0踩

行业应用

原创新闻 构建多CPU架构支持的Docker镜像

2018-01-24 10:40 by 副主编 jihong10102006 评论(0) 有11100人浏览
引用
作者简介:胡晓亮目前就职于IBM Platform Computing 系统科技部云计算部门,担任云计算开发部工程师。自2013年8月开始参与OpenStack,然后又转战Spark,目前工作在K8S相关领域。
责编:钱曙光(qianshg@csdn.net)

Docker简介

由于基于Hypervisor虚拟化技术仍然存在一些性能和资源使用效率方面的问题,近3年来容器技术席卷了整个互联网应用乃至IT界的技术革新,成为一种被大家广泛认可的服务器资源共享技术。它从根本上变革了应用程序的开发和发布方式,经过爆炸式的成长,容积技术的翘楚Docker实际上已经成为了容器格式和运行时的标准,大量流行的开源应用程序都宣布支持容器化,并且一些企业级的应用程序也开始往容器上迁移, Docker容器世界欣欣向荣。

Multi architecture Docker镜像

Multi architecture Docker镜像的支持让Docker向自己宣称的口号 “Build, Ship, and Run Any App, Anywhere” 更近了一大步。 那什么是Multi architecture Docker镜像呢?我们可以通过一个例子来说明。我们知道JAVA语言编写的应用程序是 “Write once, run anywhere”,它体现了JAVA跨平台的特性,但是JAVA程序的运行环境JVM(JAVA 虚拟机)却不是跨平台的,它是JAVA应用程序和OS平台之间的一个桥梁,不同的类型的OS和CPU架构机器需要安装相应的JVM才能运行JAVA程序。而 Docker image也是一样的,它也是依赖运行平台的,我们不能把一个httpd的ppc64le/linux架构的Docker镜像运行在amd64/linux 架构的环境中,我们也不能把一个Windows镜像运行在Linux平台上,否则你会遇到 “exec format error”。早期Docker镜像存储的设计没有充分考虑到镜像Multi architecture的支持,而是简单的使用镜像存储库的前缀来区分相同应用的不同平台,并建议开发者将不同平台的镜像应该push到相对应的Docker hub的镜像仓库中,而这种糟糕的设计依然保留在最新的Docker设计文档中如下:
例如运行busybox在多个平台上,按照Docker社区的方法如下:
x86-64:     docker run -it --rm busybox or docker run -it --rm amd64/busybox
ppc64le:   docker run -it --rm ppc64le/busybox 
s390x:      docker run -it --rm s390x/busybox 

基于Docker社区的做法,对于我们自己的应用程序Docker镜像多平台支持,我们还可以采取类似方法:

1. 基于tag
x86-64:    docker run -it --rm myapp:x86-64
ppc64le:  docker run -it --rm myapp:ppc64le
s390x:      docker run -it --rm myapp:s390x

2. 基于image 名称的后缀
x86-64:    docker run -it --rm myapp_x86-64
ppc64le:  docker run -it --rm myapp_ppc64le
s390x:      docker run -it --rm myapp_s390x

不管是基于镜像存储库的前缀,或者是基于tag或image名称后缀来区分不同的运行平台来pull相应的Docker镜像都不是好的设计,而好的设计是应该用户只要执行docker pull myapp就行了而不用关心容器的运行平台,Docker engine根据运行环境来pull相关的镜像,真正的做到 “Run Any App, Anywhere”。Docker社区已经注意到了这个问题,通过重新定义 v2.2 Image specification format(PR #1068)并在 Implement schema2 manifest formats(PR #1281)实现了Multi architecture Docker镜像功能。从Docker registry v2.3和Docker 1.10 开始,Docker hub就可以pull multi architecture Docker镜像了.

例如有2个Linux host,一个host(kvm-014009)arch是x86_64,另一个host(power807l )arch是ppc64le,我们分别在两个host 上运行 busybox 容器并且打印容器中基础镜像的arch, 看看是不是pull相同的镜像但是可以打印出与平台相关的输出。
x86_64 host :

[root@kvm-014009 ~]# docker run -it --rm busybox arch

Unable to find image 'busybox:latest' locally

latest: Pulling from library/busybox

67a0688b88df: Pull complete 

Digest: sha256:ac2fc418f3348815e68e266a5aa1b60bc522581c96964912560a0baacc4f5c06

Status: Downloaded newer image for busybox:latest

x86_64

ppc64le host:

[root@power807l ~]# docker run -it --rm busybox arch

Unable to find image 'busybox:latest' locally

latest: Pulling from library/busybox

219992aaea40: Pull complete 

Digest: sha256:ac2fc418f3348815e68e266a5aa1b60bc522581c96964912560a0baacc4f5c06

Status: Downloaded newer image for busybox:latest

ppc64le

我们run了相同的命令 “docker run -it –rm busybox arch” 在不同CPU architecture的host都得到了正确的运行结果,这是用户体验的一个极大的提升,用户根本不用关心 image的CPU arch 和OS的类型了。除了busybox镜像,httpd,nginx, tomcat和etcd等主流开源应用都有了Multi architecture Docker镜像支持,大家快快试试吧。

原理分析

如上文我们提到的自从Docker registry v2.3和Docker 1.10开始,Docker通过支持新的image Media 类型 manifest list 实现了Multi architecture Docker镜像功能:

1. 一个image manifest list 包含指向已经存在镜像的manifest对象列表

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

根据manifest list对象定义,我们可以通过下面的流程了解Docker是如何支持Multi architecture Docker镜像的:

动手实验
制作一个multi architecture Docker镜像最重要的是定义image的manifest list,虽然image manifest list的标准已经确定也实现了,可是客户端如何push这个image的manifest list到Docker registry依然在Docker社区争论不休,有兴趣的同学可以看一下ticket Add manifest command了解一下细节。虽然还没有Docker official的客户端工具支持,但是广大的开源爱好者们还是自己根据 v2.2 Image specification format中的定义实现一些小工具可以帮助我们制作multi architecture Docker镜像。首先给大家介绍两个小工具,他们都可以push Docker image的manifest list到Docker registry中。

1. Enhanced Docker CLI

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

2. Manifest-tool

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

实验机器
Host CPU arch OS Docker version
kvm-014009 x86_64 Linux rhel 7.3 Server: 17.03.2-ce
power807l ppc64le Linux rhel 7.4 Server: 17.05.0-ce

先决条件

  • 从source code编译出两个小工具的可执行文件 docker 和 manifest-tool,我们可以参考两个小工具github中提供的步骤,或者直接使用我编译好的x86_64平台的可执行文件
  • 有一个可用的Docker hub 账号用来push镜像,假设这个账户是huxl,并且已经docker login成功
实验目的

假设有一个叫myapp是跨平台的应用,支持x86_64和ppc64le CPU arch 和Linux, 为了简单,在假设myapp就是一个文本文件,里面只有一句话:I am x86_64 application (for x86_64) 或者 I am ppc64le application (for ppc64le), Dockerfile也很简单如下,用户可以使用一致的命令run这个myapp应用在不同的平台上。
FROM alpine

WORKDIR /opt

COPY myapp .

实验步骤:

1、使用Enhanced Docker CLI构建multi architecture Docker镜像

a. 构建myapp的x86_64镜像,并且push到Docker hub上
            [root@kvm-014314 muti-arch]# docker build -t huxl/myapp-x86_64:v1 .

            Sending build context to Docker daemon 3.072 kB

            Step 1/3 : FROM alpine

            latest: Pulling from library/alpine

            ff3a5c916c92: Pull complete 

            Digest: sha256:7df6db5aa61ae9480f52f0b3a06a140ab98d427f86d8d5de0bedab9b8df6b1c0

            Status: Downloaded newer image for alpine:latest

             ---> 3fd9065eaf02

            Step 2/3 : WORKDIR /opt

             ---> 204fec0aa91b

            Removing intermediate container 49747c6124e8

            Step 3/3 : COPY myapp .

             ---> d89721162bd0

            Removing intermediate container b63c71aebd49

            Successfully built d89721162bd0

            [root@kvm-014314 muti-arch]# docker push huxl/myapp-x86_64:v1 

            The push refers to a repository [docker.io/huxl/myapp-x86_64]

            723ba289c543: Pushed 

            7b2f1ea92884: Pushed 

            cd7100a72410: Mounted from library/alpine 

            v1: digest: sha256:ffac5d9918844da37c707e5b8690ce6f75563611bb6326daa5620fcb853bb590 size: 941

b. 构建myapp的ppc64le镜像,并且push到Docker hub上
           
[root@power807l muti-arch]# docker build -t huxl/myapp-ppc64le:v1 .

            Sending build context to Docker daemon  3.072kB

            Step 1/3 : FROM alpine

            latest: Pulling from library/alpine

            0da653ea85b5: Pull complete 

            9fd90b777cc3: Pull complete 

            Digest: sha256:7df6db5aa61ae9480f52f0b3a06a140ab98d427f86d8d5de0bedab9b8df6b1c0

            Status: Downloaded newer image for alpine:latest

             ---> 5675e84fb0f7

            Step 2/3 : WORKDIR /opt

             ---> fe7e5331969e

            Removing intermediate container 91c27a07b969

            Step 3/3 : COPY myapp .

             ---> e2e2fd0b2abb

            Removing intermediate container c24a46b56e1e

            Successfully built e2e2fd0b2abb

            Successfully tagged huxl/myapp-ppc64le:v1

            [root@power807l muti-arch]# docker push huxl/myapp-ppc64le:v1 

            The push refers to a repository [docker.io/huxl/myapp-ppc64le]

            4abe83ad0ae2: Pushed 

            30b0e74edb8c: Pushed 

            d8f649dc98c5: Pushed 

            22963f19a0a3: Mounted from library/alpine 

            v1: digest: sha256:102f93c9ae146cbf2d5247db82e4429f5964978cfda1df72a9c7e444a4840437 size: 1148

            [root@power807l muti-arch]# 

c. 创建指向myappp的x86_64和ppc64le的镜像的manifests list对象并将它push到docker hub
           
[root@kvm-014314 build]# pwd

            /root/cli/build

            [root@kvm-014314 build]# ./docker manifest create huxl/myapp:v1 huxl/myapp-x86_64:v1 huxl/myapp-ppc64le:v1

            Created manifest list docker.io/huxl/myapp:v1

            [root@kvm-014314 build]# ./docker manifest annotate huxl/myapp:v1 huxl/myapp-x86_64:v1 --os linux --arch amd64

            [root@kvm-014314 build]# ./docker manifest annotate huxl/myapp:v1 huxl/myapp-ppc64le:v1 --os linux --arch ppc64le

            [root@kvm-014314 build]# ./docker manifest push huxl/myapp:v1

            Pushed ref docker.io/huxl/myapp@sha256:102f93c9ae146cbf2d5247db82e4429f5964978cfda1df72a9c7e444a4840437 with digest: sha256:102f93c9ae146cbf2d5247db82e4429f5964978cfda1df72a9c7e444a4840437

            Pushed ref docker.io/huxl/myapp@sha256:ffac5d9918844da37c707e5b8690ce6f75563611bb6326daa5620fcb853bb590 with digest: sha256:ffac5d9918844da37c707e5b8690ce6f75563611bb6326daa5620fcb853bb590

            sha256:b1b4c2219f5f514fe5a752d158c76b3aa010fab2b1e1dbfa808755ff0848abfa

            [root@kvm-014314 build]#

d. 验证run myapp 镜像在两个host上,我们得到了不同的结果
          
 [root@kvm-014314 build]# docker run -it  --rm huxl/myapp:v1 cat /opt/myapp

            Unable to find image 'huxl/myapp:v1' locally

            v1: Pulling from huxl/myapp

            Digest: sha256:b1b4c2219f5f514fe5a752d158c76b3aa010fab2b1e1dbfa808755ff0848abfa

            Status: Downloaded newer image for huxl/myapp:v1

            I am x86_64 application

            [root@kvm-014314 build]# 


            [root@power807l muti-arch]# docker run -it  --rm huxl/myapp:v1 cat /opt/myapp

            Unable to find image 'huxl/myapp:v1' locally

            v1: Pulling from huxl/myapp

            Digest: sha256:b1b4c2219f5f514fe5a752d158c76b3aa010fab2b1e1dbfa808755ff0848abfa

            Status: Downloaded newer image for huxl/myapp:v1

            I am pcc64le application

            [root@power807l muti-arch]#

e. 从Docker hub上删除huxl/myapp:v1,后面我们使用Manifest-tool重新创建它
f. 删除本地huxl/myapp:v1镜像,为了不影响后续的实验
          
 [root@kvm-014314 manifest-tool]# docker rmi -f huxl/myapp:v1

            Untagged: huxl/myapp:v1

            Untagged: huxl/myapp@sha256:b1b4c2219f5f514fe5a752d158c76b3aa010fab2b1e1dbfa808755ff0848abfa

            [root@kvm-014314 manifest-tool]# 


            [root@power807l ~]# docker rmi -f huxl/myapp:v1

            Untagged: huxl/myapp:v1

            Untagged: huxl/myapp@sha256:b1b4c2219f5f514fe5a752d158c76b3aa010fab2b1e1dbfa808755ff0848abfa

            [root@power807l ~]# 

2、使用Manifest-tool 构建multi architecture docke的镜像

a. 创建一个yaml文件用来表述支持multi architecture的镜像myapp:v1
         
  [root@kvm-014314 manifest-tool]# pwd

            /root/manifest-tool

            [root@kvm-014314 manifest-tool]# cat myapp.yaml 

            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

            [root@kvm-014314 manifest-tool]# 

b. push myapp.yaml到docker hub
           
[root@kvm-014314 manifest-tool]# pwd

            /root/manifest-tool

            [root@kvm-014314 manifest-tool]# ./manifest-tool push from-spec myapp.yaml  

            Digest: sha256:dcf22c78689691df6d68117d55c4a4ce6b745caa38b1f31e882fc358a742c3c5 744

            [root@kvm-014314 manifest-tool]#

c. 验证run myapp 镜像在两个host上,我们都得到了正确的结果
          
 [root@kvm-014314 manifest-tool]# docker run -it  --rm huxl/myapp:v1 cat /opt/myapp

            Unable to find image 'huxl/myapp:v1' locally

            v1: Pulling from huxl/myapp

            Digest: sha256:dcf22c78689691df6d68117d55c4a4ce6b745caa38b1f31e882fc358a742c3c5

            Status: Downloaded newer image for huxl/myapp:v1

            I am x86_64 application

            [root@kvm-014314 manifest-tool]# 


            [root@power807l muti-arch]# docker run -it  --rm huxl/myapp:v1 cat /opt/myapp

            Unable to find image 'huxl/myapp:v1' locally

            v1: Pulling from huxl/myapp

            Digest: sha256:dcf22c78689691df6d68117d55c4a4ce6b745caa38b1f31e882fc358a742c3c5

            Status: Downloaded newer image for huxl/myapp:v1

            I am pcc64le application

            [root@power807l muti-arch]#

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

总结
  • Push multi architecture Docker镜像到Docker registry并不会push image的layers,它只会push一个引用,这个引用指向了已经存在的多个Docker镜像;
  • 只有multi architecture Docker镜像的创建者才需要知道这个引用背后指向具体的Docker镜像,而对最终的用户是透明的,最终用户只需要知道镜像的名字和tag就足够了;
  • 有了multi architecture Docker镜像支持,我们再也不用在脚本里面判断OS的类型和CPU的arch而去pull相应的镜像,提高CICD代码的简洁和优雅;
  • Image manifest list是极好的兼容性设计,它不但支持multi architecture Docker镜像,而且不会影响已经在的simple architecture Docker镜像的使用方式, 用户不用做二选一的艰难的决定。
  • 大小: 195.7 KB
  • 大小: 7.8 KB
  • 大小: 22.1 KB
  • 大小: 22.1 KB
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 认识webMethods

    webMethods主要解决的问题: 1,企业业务和应用系统的整合 2,业务流程合理化和持续改善 3,利用(Service-Oriented Architecture )SOA进行灵活和低成本的运维 形成了B2B,BPM, BAM,SOA等部分。 B2B:企业对企业的电子商务是webMethods的(Enterprise Service Bus)ESB的一部分. webMethods...

  • [WebMethod] 是什么意思?

    [WebMethod] 是什么意思? 在一个WebService类中,一个Public的方法能否被调用者访问就取决于这个方法是否是一个“WebMethod”,是不是就要看一下这个方法的属性了,加上[WebMethod]属性的公有方法就可以被访问,而没有加这个属性的方法就是不能被访问的。 WebMethod有6个属性: .Descri...

  • oracle 调用sap.rfc,WebMethods调用SAP RFC详细设计步骤

    本文采用WebMethos+SAP Business Connector的方式调用SAP RFC。需做以下配置与开发:1.SAP Business Connector配置1)从IE登录进入SAP Business Connector管理界面。2)单击上图中的Adapters-->SAP进入如下SAP服务器连接页面:3)单击上图中SAP Server Name或Add SAP Server链接...

  • webMethods-EDI后台流量统计

    在系统运维时,EDI流量的统计可以作为一个运营的数据指标,反馈webMethods平台某客户之间的业务流量的大小。 可以使用如下语句查询,主要是以自己的Partner Name和客户的Partner Name,以及流量的起止时间为参数,其它的可以使用消息处理状态,具体消息类型等参数,查询出更加具体的流量统计信息。 /*某客户的接收和发送的流量之和*/ select '某客户名称' Custo...

  • 利用ASP.NET快速开发一款Web应用

    需要用到的技术 .NET CORE 2.1:一个跨平台的高性能开源框架,用于生成启用云且连接 Internet 的新式应用 ASP.NET MVC:一种使用“模型-视图-控制器”设计模式构建 Web 应用和 API 的框架 ASP Razor Page:一种混合HTML和.NET语言而开发的服务端页面 SQL Server:一种关系型数据库 EF Code First:代码优先实体框架,一种迁移脚手架工具,以代码模型类为驱动的数据库表结构自动构建与更新同步工具。 BootStrap/EChart

  • ASP.NET 创建、发布、使用Web服务的详细方法

    一、创建Web服务 1.首先,打开VS(本例以VS2017为例) 创建一个ASP.NET Web 应用程序,位置和名称自定义,本例我把这个项目创建在桌面,名字叫helloWho。然后点击【确定】,在弹出的下一个对话框中,选择“空”,其他保存默认不变,最后点击【确定】,完成项目的创建。 2.右击项目名→【添加】→【新建项】, 在弹出的“添加新项”对话框中,找的“Web服务”,给Web服务起名,本例起名为Hello。最后点击【添加】,完成Web服务的添...

  • .NET 中的 Web服务(Web Services)和WCF(Windows Communication Foundation)

    WCF 是微软在.NET 框架中推出的用于构建分布式应用程序的统一编程模型。它整合了之前微软的多种分布式通信技术,如 Web 服务、.NET Remoting、MSMQ(Microsoft Message Queuing)等,提供了一个功能强大、灵活且可扩展的通信平台。

  • C#使用Asp.Net创建Web Service接口并调用

    开发工具: Visual Studio 2022 Current (免费社区版)框架版本: .net framework4.7.2,更高的.net 5 、net6貌似没有默认提供带web service的asp.net 应用模板了。确保VS的工作负荷有勾选下方箭头所指的模块确认环境没有问题之后就可以开始创建项目了。

  • 【C# 10 和 .NET 6】构建和使用 Web 服务(第16章)

    Building and Consuming Web Services构建和使用 Web 服务本章介绍如何使用 ASP.NET Core Web API 构建 Web 服务(也称为 HTTP 或 REST 服务),以及如何使用 HTTP 客户端使用 Web 服务,这些客户端可以是任何其他类型的 .NET 应用程序,包括网站或移动设备或 桌面应用程序。本章需要您在第 10 章“使用 Entity ...

  • 【.NET全栈】ASP.NET开发Web应用——Web部件技术

    ASP.NET中的Web组件技术,特别是Web部件(Web Parts),是一种用于创建允许终端用户直接通过浏览器修改网页内容、外观和行为的集成式控件集。这些控件提供了丰富的功能和灵活性,使得开发人员能够构建出高度可定制的Web应用程序。一、Web部件概述定义与功能ASP.NET Web部件是一组集成控件,用于创建网站,使最终用户可以直接从浏览器修改网页的内容、外观和行为。这些修改可以应用于网站上的所有用户或个别用户。

  • asp.net网站服务器搭建之从零开始

    一 IIS(Internet Information Services)安装:  1.选择"控制面板"。  2.点"添加或删除程序"。   3.选择"添加/删除Windows组件",选中IIS,把系统安装盘放到光驱中,点下一步就可以了。  4. 安装成功后,“控制面板\管理工具”里会有“Internet 信息服务”一项。 二 asp.net环境配置:  下载地址:http://...

  • 使用asp.net状态服务

    1.配置文件          <configuration>         <system.web>           <sessionState timeout="20" mode="StateServer" stateConnectionString="tcpip=192.168.0.122:42424"></sessionSt...

  • .NET学习摘要

    1、用SqlDataSource访问数据库库的方法: 往sql里面传参数的方法: SqlDS_Search.SelectParameters.Clear();//先清空,好习惯 SqlDS_Search.SelectParameters.Add("部门",部门参数的值); 2、Gridview 中显示某个字段的方法 Gridview中可以调用后台定义的函数。 例如: 后台...

  • 在C#项目中如何添加“Web引用”?

    解决方案 1.打开项目; 2.右键单击‚引用„,在弹出的菜单中选择‚添加服务引用…„; 3.在弹出的对话框‚添加服务引用„左下角单击„高级…‚按钮; 4.在弹出的对话框„服务引用设置‚左下角单击„添加Web引用…„按钮; 5.在弹出的对话框‚添加Web引用„中可以选择‚此解决方案中的Web服务„、‚本地计算机上的Web服务„…,然后更改一下‚Web

  • 请确保 ASP.NET State Service (ASP.NET 状态服务)已启动解决办法

    请确保 ASP.NET State Service (ASP.NET 状态服务)已启动解决办法   2007-09-24 14:09:40|  分类: ASP.net(C#) |  标签: |字号大中小 订阅 异常详细信息: System.Web.HttpException: 无法向会话状态服务器发出会话状态请求。请确保已启动 ASP.NET State service

  • 使用 C# 编写简易 ASP.NET Web 服务器

    使用 C# 编写简易 ASP.NET Web 服务器 如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/07/16/use-csharp-write-aspnet-web-server/。   你是否有过这样的需求——想运行 ASP.NET 程序,又不想安装 IIS 或者 V

  • ASP.NET使用WebMethod

    将普通页面的方法公布为WebMethod,以Javascript形式访问。 1 方法要public static修饰,返回类型最好是string。2 方法前添加[WebMethod] 特性。3 Client端访问时要使用Post方法,和Json作为数据形式进行交互。否则会整页HTML返回。4 在jQuery访问时,回调中的data.d才时真正的返回内容。5 访问URL为: http://abc....

  • webMethods之Developer (1)

    现在开始Developer的内容。Developer我认为是webMethods开发的最重要的IDE。本文先讲一些相关概念。Service这里的service很像我们平常程序中的函数,doc:Integration Server is a service-base integration broker. A service is a process that may be invoked

Global site tag (gtag.js) - Google Analytics