往往在大促等高峰时段都需要对流量提前预估,但实际上预先计算好的资源和应用容量,依然可能不足以支撑流量高峰,需要紧急扩容;而容器技术则非常适合这种场景,在需要时快速地、自动弹性伸缩。那么在业务需求极速上升的情况下,大量服务器资源启动时如何抗住并发部署的压力呢?
在本次双十一期间容器镜像服务参与并提供了服务支撑,其具备在十分钟之内快速万台服务其部署的能力。
作为一种轻量级的虚拟化技术,容器技术所具备的敏捷、可移植、可控性,使得它一经推出就受到众多开发者的追捧。但其实更重要的是,容器技术定义了一种标准化的交付方式——容器镜像。
容器镜像将应用的代码以及代码环境依赖都都打包在一起,这是一个与环境无关的交付物,可以应用在软件生命周期的任何阶段。就像集装箱改变了传统的运输体系,创造了容器镜像的容器技术彻底改变了传统的软件交付模式。
纵观全球,整个容器技术在近三年得到了爆发式的增长。据统计有67%的企业在生产环节或者尝试在生产环节中使用Docker,帮助他们敏捷进化,提高研发交付的效率。据Docker Con 2017的统计,近三年应用数增长了30倍,约有百万级别的容器化应用数。而容器镜像的拉取个数,近三年更是趋于了指数级别增长,承载了约110亿次拉取。
DockerCon2017年容器镜像拉取情况的最新统计
早在2015年,阿里巴巴就在尝试使用容器技术。2016年双十一就已经将所有交易核心应用容器化,几十万容器撑起了双 11 交易 17.5 万笔/秒的下单峰值。而在今年双十一,阿里巴巴已在集团范围实现在线服务全部容器化,内部已达到百万级容器部署规模,其中双十一交易峰值到32.5万笔/秒并且可以实现十分钟内万台服务器的快速部署。
截止目前,容器镜像服务支撑了集团10万镜像的托管,共计2亿次的镜像下载量。
在早期的容器推行演练中,由于当时发布系统日均的发布量上万,很多应用的规模开始破万,发布失败率开始增高,影响到了业务的正常迭代流程。这个困境的根本问题在于发布过程大量大应用镜像拉取的需求,而应用镜像内容过于冗余臃肿,彼时存在大量超过5G的大镜像,文件服务器扛不住大量的请求。
为了解决多规模、并发情况下容器镜像的获取问题,我们考虑了容器镜像大小、容器内容加速及流控、镜像Registry性能等三个大维度的优化。
容器镜像大小优化
Action 1:之前将所有的构建过程编写在同一个Dockerfile中,包括应用及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:镜像臃肿、镜像层次嵌套深、也可能存在源代码泄露的风险。我们进行了多阶段镜像构建优化,将镜像制作过程中的中间产物与最终镜像构建产物分离,形成最精简的应用镜像。
多阶段镜像构建优化后获取最精简应用镜像
Action 2:将功能统一的命令聚合到同一层来完成,将使用频繁的应用或环境制作成基础镜像复用,尽可能减少镜像的层数。
容器内容加速和流控
在大规模的镜像分发场景之下,优化镜像本身的大小作用有限,我们依然需要考虑如何从系统上提升镜像拉取的性能。最初很容易想到服务器扩容,可是扩容后又发现后端存储成为瓶颈。此外,大量来自不同IDC的客户端请求消耗了巨大的网络带宽,造成网络拥堵。同时,很多业务走向国际化,大量的应用部署在海外,海外服务器下载要回源国内,浪费了大量的国际带宽,而且还很慢;如果传输大文件,网络环境差,失败的话又得重来一遍,效率极低。
为了解决这些问题,阿里推出了蜻蜓这个产品。蜻蜓通过使用P2P技术同时结合智能压缩、智能流控等多种创新技术,解决大规模文件下载以及跨网络隔离等场景下各种文件分发难题,大幅提高数据预热、大规模容器镜像分发等业务能力。
在本地机器使用了分层的方式来下载镜像,下面介绍下DockerPull的执行过程:
Docker 镜像分层下载图
Docker Daemon调用RegistryAPI得到镜像的Manifest,从Manifest中能算出每层的URL,Daemon随后把所有镜像层从Registry并行下载到Host本地仓库。
所以最终,镜像传输的问题变成了各镜像层文件的并行下载的问题。而蜻蜓擅长的正是将每层镜像文件从Registry用P2P模式传输到本地仓库中。
那么具体又是如何做到的呢?
事实上蜻蜓会在Host上启动proxy,Docker Engine的所有命令请求都会通过这个proxy,我们看下图:
蜻蜓P2P容器镜像分发示意图
首先,docker pull命令,会被dfget proxy截获。然后,由dfget proxy向CM发送调度请求,CM在收到请求后会检查对应的下载文件是否已经被缓存到本地,如果没有被缓存,则会从Registry中下载对应的文件,并生成种子分块数据(种子分块数据一旦生成就可以立即被使用);如果已经被缓存,则直接生成分块任务,请求者解析相应的分块任务,并从其他peer或者supernode中下载分块数据,当某个Layer的所有分块下载完成后,一个Layer也就下载完毕了,同样,当所有的Layer下载完成后,整个镜像也就下载完成了。
蜻蜓支持多种容器技术,对容器本身无需做任何改造,镜像分发比natvie方式提速可高达57倍,Registry网络出流量降低99.5%以上。为阿里巴巴业务的极速扩张和双十一大促保驾护航。
镜像Registry性能优化
蜻蜓利用P2P的模式解决了从Registry获取镜像层并传输到本地的问题,不过当镜像拉取规模在几万并发的量级的时候,从Registry获取镜像的Manifest也会成为性能瓶颈。容器镜像服务从代码层面、基础设施层面做了很多定制化的增强:
在代码层面:容器镜像服务增加了对于Docker Registry优化,根据之前的镜像请求,自动分析热点数据并增加了热点数据的缓存,从容应对大规模并发下镜像Manifest的拉取。增加了对镜像下载源的动态判断,根据镜像下载请求的不同来源,自动返回离镜像下载最近的Registry地址。
在基础设施层面:为了应对流量的突发,容器镜像服务加强了针对Registry流量、存储的多维度监控,定时进行监控探活,并且实时收集监控数据,当达到监控阈值,Registry会自动进行报警和基础设施的弹性扩容。
自2015年起面向阿里集团内部和对阿里云容器服务提供支撑以来,阿里云容器镜像技术积累了深厚的经验。一般而言,大家认为容器镜像服务是为用户提供了安全稳定的镜像托管能力,但是实际上并不至于此:除了镜像托管以及镜像的上传下载之外,容器镜像服务还包含了从镜像构建到应用部署等一整套的DevOps能力。
为了将阿里巴巴在容器技术上的积累带给云上用户,容器镜像服务于2017年10月30日正式对外公测。容器镜像服务(ContainerRegistry)免费提供了安全的镜像托管能力,稳定的国内外镜像构建服务,便捷的镜像授权功能,方便用户在云上进行容器镜像全生命周期管理,体验容器技术带来的敏捷变革。
1)全球多地域支持及镜像加速器:
阿里云容器镜像服务提供了全球多地域支持,用户可以在自己业务地就近托管容器镜像,保障应用镜像的极速上传、下载操作。我们也为每一位用户提供了新一代专属镜像加速器,通过镜像加速器可以快速获取国外优秀的镜像。镜像加速器采用了自主研发的智能路由及动态缓存技术,极大提升了镜像的下载速度和用户体验。并且完全兼容 Docker 原生参数配置方式,支持 Linux、MacOS、Windows 三大平台。目前,容器镜像服务已经加速了千万次的镜像拉取,帮助用户节省超过十万个小时。
2)多阶段构建:
阿里云容器镜像服务提供了丰富稳定的镜像构建功能,包含自动构建、海外构建、多阶段构建(multi-stage build)支持,方便打造云上容器DevOps最佳实践。用户可以将应用代码托管在阿里云Code、Github、Bitbucket或者自建的GitLab之上,通过容器镜像服务多阶段构建功能或者阿里云CodePipline进行代码编译测试,构建完成后的镜像将推送至容器镜像服务托管。最后通过容器镜像服务上的webhook,动态通知容器服务集群上相应的应用重新部署。
通过整个解决方案,用户在将代码提交至线上之后,可以实现自动的代码测试,测试通过后应用自动构建成镜像,最终部署到测试、预发或者生产环境的集群上。
阿里云容器化DevOps流程图
3) 镜像安全扫描
镜像已经成为企业的核心资产,企业软件交付流水线的中心,线上的应用的安全问题也是至关重要的。容器镜像服务提供了便捷的镜像安全扫描功能,提供多维度的镜像漏洞报告。镜像漏洞报告中包含漏洞的CVE编号、漏洞的等级、漏洞位置及官方和社区提供的漏洞修复方案。
阿里云容器镜像安全扫描示意图
容器镜像服务通过Registry性能优化,蜻蜓通过P2P技术结合智能压缩和流控等方案,共同解决了大规模文件下载以及跨网络隔离等场景下各种文件分发难题,在阿里已然成为重要的基础设施之一,为业务的极速扩张和双十一大促保驾护航。
截止到目前为止,已经有数万用户经过容器镜像服务(ContainerRegistry)享受了安全的镜像托管能力、稳定的国内外镜像构建服务、便捷的镜像授权功能,通过容器镜像进行全生命周期管理。容器镜像服务简化了Registry的搭建运维工作,支持多地域的镜像托管,并联合容器服务、CodePipeline等云产品,为用户打造云上使用Docker的一体化体验。
作者简介:
阿里云容器服务团队成立于2015年,于2016年公有云容器服务正式商业化、专有云企业版正式发布、产品实现国际化,于今年发布专有云敏捷版,全面升级提供Kubernetes和Swarm的支持。