关注世界领先 DevOps 平台 JFrog

背景

Cars.com 是美国的汽车门户网站,为用户提供各种购车相关的信息和资讯,类似于国内的汽车之家。

他们之前的技术栈是比较传统的 Java Web 结构:Java 7, Websphere/Weblogic, Oracle Linux, IBM 硬件,Oracle 数据库 。开发语言包含 Java,NodeJs,Go。随着网站宣传的投入,Cars.com 的流量也变大了。

· 3000万访问者 / 月
· 470万车辆信息
· 每天处理200万张图片请求
· 每天服务端处理1亿次请求

问题来了,流量变大之后,传统的架构显得力不从心。同时,软件交付流程也成为了瓶颈,来看看他们的痛点。

痛点

· 两套操作系统和中间件
操作系统和中间件的选型不同,各自分别包含Websphere, Weblogic, Oracle Linux, Redhat Linux, AIX等等。

· 每套运行环境需要5份
包含开发者环境,功能测试环境,集成测试环境,性能测试环境,生产环境。

· 10个 Web 应用,100多个服务需要部署。

由于环境的差异性,上线流程的复杂性,导致 Cars.com 的团队经常碰到的问题是:为什么代码在这个环境能运行,在另外一个环境不行?久而久之为团队带来大量重复的定位环境问题的工作,严重影响了开发进度。

Cars.com 总结了他们的诉求 – 实现不可变基础设施

· 统一上线流程。

· 具备实时扩展的能力,应对高峰期流量。

· 当服务出现问题,能够自动回滚,自动恢复。

使用 Docker 实现不可变基础设施

为什么选择 Docker?

· 提供一致性,可预期的环境。
使用 Docker 可以屏蔽环境的差异,解决维护5份环境的痛点。

· 实现微服务部署。
Cars.com 底层有100多个服务,服务如果不能单独部署,会有造成构建时间长,上线周期长,排除问题困难等问题。 实现微服务的独立部署,可以加速软件上线速度,降低问题排除难度。

· 秒级故障恢复。
Docker 作为服务的载体,具备快速销毁,快速上线,快速回滚的能力。一旦线上服务出问题,可以快速回滚到上一个版本。

· 实现蓝绿部署,金丝雀发布。
快速发布环境,让一部分用户体验某些新功能,待功能被快速验证得到积极的反馈之后,再进行大面积部署。

构建一个通用 Docker 镜像

为什么需要构建通用的 Docker 镜像?

· 公司内部有很多镜像,当有新的环境需要搭建时,要把镜像从仓库一个一个都拷贝到开发者的机器。

· 多语言开发团队,包括 JavaScript,Java,Go 等等,每种语言打包的镜像体积过大,导致镜像构建,下载速度慢,影响开发效率。

经过一系列实践,Cars.com 总结出来了通用镜像的方案:

· 采用 Alpine Linux 作为基础镜像
Alpine Linux 系统的文件大小非常小,可以达到5MB。

· 轻量级的容器

- 删除 Package Manager 里面的所有Source。

- 在软件安装完之后,删除安装包,删除没有用到的依赖,删除临时文件。

- 剪裁官方镜像。剪裁 Node 镜像,Node 官方镜像最新版达到了649MB,他们将这个镜像缩减到55MB。JDK 缩减到122MB,Tomcat 从357MB 缩减到181MB。

在裁剪镜像大小的实践中,Artifactory 中的 Docker info 提供了帮助,可以在 Docker info 中看到每次打包的镜像 Layer 的实际大小,通过裁剪每层 Layer 的大小,最终达到缩小镜像的目的。

仓库的需求

每个团队都有管理包的需求,开发者要管理 Jar,War,静态文件,系统 Admin 要管理不同的 Linux 发行版,每种语言都用不同的包管理系统,维护这5,6种二进制包仓库非常麻烦,他们使用了 Artifactory 作为一站式包管理平台。理由:

· 本地搭建的仓库
大大提升所有语言构建,打包的速度。

· 支持 NPM modules,Docker 注册中心,Maven,Go。

· 支持 Linux 的包管理工具(RPM,Debian)。

· 和 Jenkins/Bamboo/MSBuild/TFS 等工具集成,收集构建信息。

· 元数据支持,并且提供 Rest API。

Cars.com 通过为 Docker 镜像,War 包设置元数据,使得任何包都可以通过 Artifactory Query Language 根据元数据,过滤出符合上线条件的包,打包到镜像里,部署到环境上。

封装 Docker API – PowerTrain

  为什么要封装Docker API?

· 需要即时响应快速上线,回滚,支持滚动升级,动态绑定端口。

· 保证开发者环境里能跑的应用,在生产环境里也能跑,实现不可变基础设施。

· 声明式配置管理。

PowerTrain 的配置文件 powertrain.mk 解决的问题是将不同环境中变化的部分,作为变量,存在文件里,当需要生成某个环境时,只需将需要的变量传递给 PowerTrain,即可获取对应环境所需的依赖,实现按需搭建环境。

PowerTrain 也封装了一些 Docker 的常用操作,例如 Docker build,pull,push 等等,在这基础之上增加的一些定制化的信息,来适应灵活的镜像构建和部署。利用 Docker 的轻量级部署特性,实现快速搭建环境,快速上线服务。PowerTrain 的具体的实现可以在 Carsdotcom 的 Github 上找到源代码。

持续集成流水线

· 开发提交代码到 Bitbucket。

· Commit 触发 Jenkins 的 Webhook, 执行构建。

· Jenkins 执行 PowerTrain build。

· 从 Artifactory 找到对应的 War 文件,基础镜像,构建出新的镜像。

· 快速搭建测试环境,使用 Docker 作为载体运行 war 包,进行测试(功能,接口,性能) 。

持续交付流水线

· 镜像通过测试,会升级到 Artifactory 的生产仓库。
· 通过 Jenkins 触发 PowerTrain 命令,部署到生产环境。

要部署到不同的环境,只需要执行不同的 powertrain.mk 文件,就能拉取不同的依赖,部署到不同的环境。

总结

Cars.com 通过一系列的实践,完成了从传统 Java Web 应用到容器化的转型。得到的收获:

· 使用 Docker 屏蔽之前5份环境的差异,实现一次构建,处处运行,大大减少运维中的重复性工作。使用 PowerTrain 的配置文件,让上线流程脚本化,实现不可变基础设施。

· 使用 Artifactory 作为多语言的本地仓库,大大提高获取第三方依赖,和管理自研件的效率。

· 剪裁 Docker 镜像,实现轻量级镜像发布,在突发流量到来时能够实现动态扩容,以及快速故障恢复。

下载JFrog Artifactory 开源版(代替 Nexus):
http://www.jfrogchina.com/open-source/

下载JFrog Artifactory 企业版(免费试用):
https://www.jfrog.com/artifactory/free-trial/?lang=zh-hans#High-Availability

关于JFrog
世界领先DevOps平台
公司成立于2008年,在美国、以色列、法国、西班牙,以及中国北京市拥有超过200名员工。JFrog 拥有3000多个付费客户,其中知名公司包括如腾讯、谷歌、思科、Netflix、亚马逊、苹果等。连续两年,JFrog 被德勤评选为50家发展最快的技术公司之一,并被评为硅谷增长最快的私营企业之一。