分享的是使用Jenkins + Artifactory + Kubernetes + Helm进行企业级CICD流水线搭建的过程。
一、搭建企业级容器持续交付流水线

首先我们看看企业级的持续交付流水线应该长成什么样子。上图描述的是单团队持续交付模型,可以看到虚线的部分是手工步骤,实线部分是自动化步骤。
大多数公司的流水线只有Jenkins不断地进行持续构建、测试和部署,而缺乏质量关卡,难以把握交付物的质量。如果我每天都交付得很快,但交付的质量很糟糕,那么带来的肯定是灾难。所以我们强烈建议公司内部自己画出这样的流程图,看看自己持续交付的瓶颈在哪里。
发布包晋级(Promotion)

很多公司的实践是在构建包构建完成之后,上传到统一的制品库,将需求、代码分支信息、测试结果、漏洞扫描结果记录在构建包上,带着这些交付的元数据进入部署环境。这样,开发和运维之间的交接变得顺畅,大大提高交付效率,有了质量关卡的设定,也能清楚告诉团队哪些环境是短板、哪些可以改进,从而有的放矢,提升质量。
二进制包关联代码坐标和需求

将元数据记录在构建包上之后,运维就会方便地看到以上的内容,在部署的时候就能明确上线了哪些需求、有没有通过必要的质量检测,就能保证线上不出问题。
持续交付流水线
然后我们来看看我要搭建的Jenkins + Artifactory + Kubernetes + Helm流水线的Jenkins任务:

我们的流水线会包含以上的任务,包含构建War包、创建Docker镜像、进行Docker镜像的漏洞扫描、创建HelmChart、使用HelmChart进行Kubernetes集群的部署等。
首先会用Jenkins的Groovy语法创建War包构建的任务。

可以看到,这里可以指定构建时所需要的依赖仓库。对于大型企业来讲,一般需要公司内部有统一的、受信的单一仓库来统一管理所有外网的依赖,提供安全管控的能力。

有了构建包之后,将这个包上传到Artifactory,即开始对依赖的开源软件包进行漏洞扫描,避免出现struts2这样的高危漏洞。

除了关注开源包的漏洞信息,还要看这些漏洞包的影响范围。
二、Kubernetes CICD实践
Know your limits
由于我们每个研发、每个分支都有独立的Kubernetes环境进行容器化的部署,一旦研发开始大规模的测试,资源必然会有出现瓶颈的时候。所以一定要对Pod进行资源的限制。同时,对Pod里的应用也需要进行限制,例如Java的内存限制、MQ和Mongo的内存限制。

如上图所示,我们对应用进行的资源的限制。
Multiple containers in a Pod

通常一个Pod里不能完成所有的事情,所以Pod通常会有多个容器。我们会配置init的容器,去配置存储和配置信息,同时会配置Sidecar容器去收集日志、监控和代理。
Managing an application's lifecycle

我们在发布Kubernetes应用时,往往会发布多个组件、模块,从而对应了多个yaml文件。而其中某个模块升级时,这些文件的关联关系就会变得错综复杂,同时,对于“如何管理多个环境的yaml文件里的配置信息?如何回滚到上一个稳定微服务架构应用的部署?”等问题,我们也要关注和思考。
Here comes Helm

Helm是Kubernetes的官方包管理工具,我们使用Helm来解决上面提到的问题。你的应用所关联的所有模块都用一个文件进行描述——HelmChart。每次部署的应用都会对应不同版本的Chart,用于做灰度发布、回滚。Chart里所有和环境、配置相关的信息都存储在values.yaml文件里,从而能够应对不同的环境,例如开发环境有dev-values.yaml、生产环境有prod-values.yaml。
More Helm charts

Helm的使用方式极其简单,使用命令Helm install artifactory即可部署一个Artifactory应用到Kubernetes里,也可以用同样的方式很多其他的应用,比如Jenkins等等。
Visibility in Kubernetes?

在应用监控这块,我们使用EFK(ElasticSearch、Fluentd、Kibana)进行所有Pod里日志的收集、索引以及可视化。我们不给研发SSH到Pod里看日志的权限,而是必须通过我们的EFK平台进行日志检索,虽然对我们提出了很高的要求,但最终还是满足了大部分研发的需求,提升了研发定位错误的能力。
Use with your CI

我们也使用Jenkins Pipeline进行我们的流水线。得益于Artifactory的全语言仓库,我们自身应用需要的war包、Tomcat、Docker镜像都从Artifactory统一进行拉取,并且使用Helm仓库进行Kubernetes集群应用的部署。
JFrog and Kubernetes

目前我们已经能够实现:
CI/CD流水线直接对接到Kubernetes进行测试,均使用Helm进行部署:
每个研发的每个分支具备独立的测试沙箱环境,供研发进行自测;
每周100+不同产品线的任意版本组合部署,每次部署超过50种微服务。
对应Kubernetes的用户,我们提供Helm Chart帮助用户快速部署我们的产品线,包括JFrog Artifactory、Xray、MissionControl等等。
三、总结
目前,我们的Artifactory已经支持高可用的Maven、Npm私服、Docker镜像仓库、Go语言的仓库VGo、Helm仓库等全语言仓库,它会作为公司内部的Kubernetes注册中心,能够描述Docker镜像的质量信息,比如是否经过单元测试、代码扫描、性能测试、漏洞扫描等等,描述Docker镜像的质量信息,能够为研发团队提供一站式的应用交付能力,而这些能力恰恰是落地DevOps的最后一公里,也是最稀缺的能力。
网友评论