极简容器化交付 | 0命令行完成镜像上传

虽然docker、kubernetes的命令集并非十分复杂,后台操作也比较快捷,但是对于大多数徘徊在容器化门口的企业和个人用户来说,仍旧是一块心病,docker or not docker, that‘s a question,SWR服务通过提供界面化的操作,屏蔽原生命令行,简化用户操作和技术门槛,为企业和个人用户提供极简的容器化交付平台,我们接下来会通过一系列的文章,向大家介绍SWR的这些功能特性。

今天要为大家介绍的是用户0命令行,通过WEB界面实现镜像的上传及实现原理剖析。

我们从这个最为常用并极为简单的docker push功能开始讲,为什么呢?由于我们在与客户交流过程中发现,大多数都未接触过容器化管理系统,甚至镜像,对后端操作不熟悉的他们,对页面操作是有一定需求的。目前主流的PaaS平台基本都支持通过页面操作构建镜像、创建集群、创建应用等等,它们都在不断地封装底层集群管理系统(如kubernetes)的接口,设计一款对于云下用户友好的前端页面,让尽可能多的后端复杂操作可以通过鼠标的几次点击完成。

我们可以将这个趋势解释为,用户的业务云化的成本(包括金钱成本和时间成本)越低,上云的倾向也就越大。如今,我们支持用户在页面上完成构建、部署等操作,如果可以实现镜像上传下载都在页面上完成,用户就可以在尝试云化的早期尽可能避开后端操作,将尽可能多的时间成本花在业务调试上,普通运维人员不需要熟悉docker命令,也可以从内网或者第三方镜像仓库下载镜像,上传并完成升级操作。

接下来,我们从镜像上传逻辑和镜像结构开始讲起,阐述如何去实现页面上传镜像的功能。

后端上传镜像流程分析

我们的目的是实现另一种镜像上传方式,首先要了解原生的镜像上传流程是怎样的。

上传镜像层

docker push时,最先被上传的是镜像层文件。如下面的busybox,每一行的short ID都表示着一个镜像层的sha256值,它有两个镜像层:


上传元数据文件

由于层之间有顺序依赖关系,我们可以想到,上传的层文件是不足以完备地描述整个镜像的。除了镜像层文件外,docker push的时候还额外会上传一个镜像的元数据文件。该文件主要保存了镜像的环境变量、层结构、构建信息等等,并且它的sha256值就是镜像的ID。由于字段太多,在此不详细列出各字段的含义,感兴趣的朋友可以使用docker inspect命令查看,参阅docker官方文档了解一下。

上传manifest

你们是否注意到,每个镜像在上传结束之后,屏幕上都会多一行xxx: digest: xxx size: xxx,最后一行信息的打印,标识着镜像最后一部分数据上传完成,这部分数据就是manifest,而digest后面的长ID,就是manifest的sha256值。

manifest主要是负责关联镜像的元数据文件和镜像层。在所有层都上传结束后,它才被传到仓库端的,用于校验是否所有实体文件都上传完成。通过抓包或者查阅官方文档,我们可以得知,manifest的结构是这样的:


由上述分析可知,要完备地描述一个镜像,需要存储如下数据:

镜像层

元数据文件

Manifest

我们接下来分析一下,从docker save生成的镜像包里,我们是否能获取到这些数据。

镜像压缩包结构分析

通过docker save保存镜像压缩包,解压开之后,可以发现,它的文件结构是比较有序的。


根目录下有这三个文件:


此外,包内还有多个以长ID命名的目录,每个目录下均有如下三个文件:


这里,有两个较为普遍的误区需要澄清一下:

误区一:manifest.json就是manifest

manifest里描述的是元数据文件名称,以及各个层的sha256值,此外,还有它们的大小。

而manifest.json里存放的不是完整的manifest信息,它仅仅记录了元数据文件的全路径名称,以及各个镜像层的全路径名称,没有记录各个层的sha256值和大小。

误区二:各个层所在的目录名就是镜像层的sha256值

其实目录名是用各个层的链ID(chain ID)和关联父层的链ID联合计算出来的一个特殊sha256值。这个特殊的sha256值,我们可以称之为v1 ID,它被设计于兼容较早版本(1.10之前)的docker镜像,早期版本,一个镜像中可能存在多个sha256值相同的层(如空层)。

顺带提一下,上面的链ID是docker daemon使用递归的方式将每一层与依赖的所有父层联合算出sha256得到的,它可以有效解决层相同导致目录重名的问题,具体计算方式在此就不赘述了。

明白了这两点之后,我们可以发现,镜像压缩包里是可以获取到与docker push同样完备的镜像数据的。其中,镜像层和元数据文件可以通过解压直接获取,而manifest则需要我们通过补充manifest.json获得。接下来我们看一看华为云容器镜像服务是怎么实现这一过程的。

页面上传是怎么实现的


解压并校验

镜像压缩包传至后端时,先对压缩包里的文件类型校验(普通文件、软链接、目录),确认无误之后,解压至临时目录并进行大小校验(前端上传目前有大小限制)。

此外,有一类镜像需要被过滤:通过docker save image_id > image.tar命令生成的镜像包。这类镜像是没有有效的镜像仓库和版本号信息的,我们无法判断要将其归于哪个仓库下,因此,这样的镜像可以认为是不合法的。对于页面上传而言,合法的镜像压缩包里必须有镜像仓库和版本号信息(如使用docker save repository:tag > image.tar的方式生成的镜像)。

保存实体文件

接下来,通过临时目录下的manifest.json,找到对应的元数据文件xxxx.json和各个目录下的镜像层文件进行存储。保存之前,通过元数据文件xxxx.json中各个层的sha256值,对实际镜像文件进行校验,保存过程中,我们在manifest.json的基础上,补充各个镜像层和元数据文件的sha256值、大小等信息,得到manifest。

在这里有个需要注意的地方,层文件一般都是普通文件,但是个别情况下(如docker1.10之前的版本),层文件可能是软链接,指向同镜像压缩包里的的另一个层文件,如果要兼容老版本,需要识别出这一部分特殊文件,跳过实体文件的保存。

保存元数据

最后,将镜像层元数据列表和manifest元数据在同一事务里存进数据库,保证镜像元数据的存储是一个原子操作,则镜像所有数据保存完成。该镜像可以通过docker pull的方式正常下载。

这只是华为云容器镜像服务基于优化用户体验的目的而开发的特性之一,我们一直致力于降低云容器技术的槛和使用成本,推进软件行业容器化的进程,希望有兴趣的朋友可以来体验一下,并提供你们宝贵的意见。

除此之外,我们最近还新上线了容器持续交付的工具,可以将您的源码快速编译、构建成镜像,省去本地编写Dockerfile、镜像制作、发布和部署的繁琐过程,后面文章我们将详细为您介绍。

原文地址:http://blog.51cto.com/14051317/2343661

时间: 2024-08-29 22:09:43

极简容器化交付 | 0命令行完成镜像上传的相关文章

极简容器化交付 | 部署组件分析

之前给大家讲了构建镜像的原理,那么有了镜像之后,我们怎么样能将它快速的部署到kuberentes集群上呢? 早期,大家都习惯于使用kubernetes接口,或者cli命令行来完成这些操作,但是yaml文件语法的复杂性.大量容器和kuernetes的概念,让人难以理解,无疑成为容器化交付路上的又不障碍. 为了解决这些问题,华为云容器服务推出了向导式镜像部署,通过一步步引导.对复杂概念的屏蔽或抽象,在一定程度上降低了用户首次部署镜像的难度,但是灵活度相对较差,对于经常变更版本的场景,还是需要使用原生

FileZilla命令行实现文件上传以及CreateProcess实现静默调用

应用需求:         用户在选择渲染作业时面临两种情况:一是选择用户远程存储上的文件:二是选择本地文件系统中的文件进行渲染.由于渲染任务是在远程主机上进行的,实际进行渲染时源文件也是在ftp目录中获取的,因此当用户选择本地文件系统中的文件时,文件必须上传到ftp上的指定目录中,远程主机才能正确获取到文件的路径,下载后进行文件渲染,然后将渲染结果保存在ftp的指定路径下.因此,需求就是当用户选择本地文件系统中的文件时,文件要自动上传到ftp的目录中,供渲染程序调用执行. 解决方案分析: 原有

在linux命令行利用SecureCRT上传下载文件

一般来说,linux服务器大多是通过ssh客户端来进行远程的登陆和管理的,使用ssh登陆linux主机以后,如何能够快速的和本地机器进行文件的交互呢,也就是上传和下载文件到服务器和本地?与ssh有关的两个命令可以提供很方便的操作:    sz:将选定的文件发送(send)到本地机器    rz:运行该命令会弹出一个文件选择窗口,从本地选择文件上传到服务器(receive) rz,sz是便是Linux/Unix同Windows进行ZModem文件传输的命令行工具 windows端需要支持ZMode

telnet(ssh)等等 远程到linux(比如ubuntu)服务器,让后通过命令行在服务器上使用vpn

这篇文章的作用是:telnet(ssh)等等 远程到linux(比如ubuntu)服务器,让后通过命令行在服务器上使用vpn. 我在网上查了很多资料,但是按照上面的操作大都行不通,估计是linux的环境上存在差异. 下面的步骤是远程登录到(server)服务器,在服务器上使用vpn. 1.下载安装vpn相关的package [email protected]:~#sudo apt-get install pptpd network-manager-pptp network-manager-vpn

使用终端命令行将本地项目上传到Github

使用终端命令行将本地项目上传到Github 转自https://blog.csdn.net/fishball1/article/details/52020305 对于IOS开发者来说,Github的使用是必须要掌握的一种技能,而把项目由本地上传到Github有多种方式,1开发工具Xcode配置Git,由Xcode-->Source Control-->Commit:2使用Github客户端上传代码:3使用终端命令行上传到Github.其中我的Github地址有我根据实际项目制作的一个配置说明书

tp5.0整合七牛云图片上传

转:https://www.cnblogs.com/adobe-lin/p/7699638.html 这里以上传图片为例 上传其他文件也是大同小异 使用composer安装gmars/tp5-qiniu 安装成功则在vendor目录下多出一个目录 这个目录含有整合七牛云的所有类包等文件 控制器中添加upload方法 public function upload() { if(request()->isPost()) { $qiniu = new \gmars\qiniu\Qiniu('你的ak'

SecureCRT使用sz和rz命令进行文件的上传和下载

SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. 本地文件夹可以通过Options-->Session Options中进行设置.

Python远程登录Linux操作系统,执行命令、创建目录、上传及下载文件

主要是创建文件: #! /bin/bash # -*- coding: utf-8 -*- import paramiko import os ssh = paramiko.SSHClient() key = paramiko.AutoAddPolicy() ssh.set_missing_host_key_policy(key) pkey = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa') paramiko.util.log

C# .NET 0命令行安装Windows服务程序

设计原则:万物皆对象 背景:在我的项目中,即需要与硬件通过Socket连接通讯,又需要给App提供Wcf服务操作接口,虽然都完成了,但是却是一个控制台(虽然我很喜欢控制台,因为它简单易用),把它放到服务器运行,总有一个黑乎乎的窗口,总感觉不雅(原谅我的强迫症).于是各种百度谷歌如何创建运行WIndows服务程序,就像SqlServer数据那样在后台默默运行奉献就可以了. 但是,很多都是那么的麻烦,需要批处理什么的,而我这个人向来喜欢简洁,于是便设计了这么个Windows服务辅助类,没错,就是0命