持续交付工具Jenkins
简介
Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。
最新版本
2.249.2 (2020-10-07)
版本历史
https://www.jenkins.io/zh/changelog-stable/
**备注:**版本更新频繁,社区活跃度高。公司目前在使用:2.133
价值
提效
持续交付能够向各个协作部门输出统一的标准、流程和工具,提升沟通效率;并且通过大量的自动化,进一步提升各部门工作效率;还可以快速集成,把各个分散的团队,无论是横向的业务研发团队,还是纵向的技术框架团队,紧紧地联系在一起,共同进退。
整个提效过程包括编译速度、发布速度、回滚速度、自动化测试速度等等
标准、规范、流程落地载体
持续交付是一整套平台工具的落地,几乎涵盖了研发的整个生命周期,是天然的、最佳的载体。另外,持续交付的落地本身就伴随着各类标准、规范、流程的制定和实施,可以说两者相互依存,是非常好的管理思想落地方案。
企业特性
部署方式
jenkins和jenkins X:
-
Jenkins 平台中遇到的一个主要问题来自静态的代理/执行器,在高峰时间有时构建队列很长。
-
Jenkins X 基于 Jenkins 和 Kubernetes 实现持续交付、部署在k8s中的容器,在高并发的时候可以有效的进行动态伸缩pod、提高执行器并非数。
认证管理
通过ldap对jenkins进行统一账号管理
授权管理
jenkins 具备详细的环境和人员管理的权限
多云环境
通过对等网络、专线、vpn、公网等方式进行打通
版本历史/包管理
- 可快速回滚
- 根据收集各方需求,大概需要存储1年/半年
环境管理
开发环境
微服务架构下,单机已经无法完整地运行业务应用,这就需要开发环境内包含一套完整的业务应用依赖以及相关的基础设施,以保证业务开发同学能在本地完成开发测试。
功能测试环境
在开发环境下,每个下游依赖应用都只有一个可用的 stable 版本。而在实际的开发过程中,由于项目的并行开发,往往会同时存在多个可依赖的版本。而每个项目组的同学在测试时,都希望测试过程中的关键依赖应用是可以被独占的,版本是固定的,不会被其他项目组干扰。所以,一套独立的功能测试环境就很有必要了。通常,互联网企业会通过中间件的方式分割出一块隔离区域,在功能测试环境中创建多个子环境来解决这个问题。
验收测试环境
验收测试环境和功能测试环境是完全隔离的。当功能测试通过后,你可以在验收测试环境进行最终的验收。它除了可以用作测试之外,还可以用作产品展示。所以,除了测试和开发人员,产品经理也是验收测试环境的主要使用者。
预发布环境
到了预发布阶段,应用已经进入了生产网络,和真实的生产应用共享同一套数据库等基础设施。预发布是正式发布前的最后一次测试,在这个环境中往往可以发现线下环境中发现不了的 Bug。这个环境的运维标准等同于生产环境,一般不允许开发人员直接登录机器。
根据不同的业务需求和部署策略,不同公司对预发布环境的实现也有所不同:
- 一种比较常见的方式是,将金丝雀发布作为预发布,从接入真实流量的集群中挑选一台或一小组机器先进行版本更新,通过手工测试以及自动化测试和监控系统验证,降低新版本发布的风险。
- 另一种做法是,独立出一组始终不接入真实流量的机器,调用在预发布环境中形成闭环。
相对于第一种方式,第二种方式对生产环境的影响更小,但需要额外的资源和维护成本。
生产环境
生产环境是用户真实使用的环境,对安全性和稳定性的要求最高。
上线整体流程图
如下图:
各环境上线流程图
开发环境
测试环境
预发布环境/生产环境
预发布环境就是我们灰度场景
流水线
代码仓库
语言支持
目前支持java、go、ios、andriod、npm等语言。
仓库
常用gitlab、gerrit、svn等
分支管理
你需要思考的几个问题如下:
- Google 和 Facebook 这两个互联网大咖都在用主干开发(Trunk Based Development,简称 TBD),我们是不是也参照它俩,采用主干开发分支策略?
- 用 Google 搜索一下,会发现有个排名很靠前的分支策略,叫“A successful Git branching model”(简称 Git Flow),它真的好用吗?团队可以直接套用吗?
- GitHub 和 GitLab 这两个当下最流行的代码管理平台,各自推出了 GitHub Flow 和 GitLab Flow,它们有什么区别?适合我使用吗?
- 像阿里、携程和美团点评这样国内知名的互联网公司,都在用什么样的分支策略?
主干开发(TBD)
主干开发是一个源代码控制的分支模型,开发者在一个称为 “trunk” 的分支(Git 称 master) 中对代码进行协作,除了发布分支外没有其他开发分支。
Google 和 Facebook 都是采用“主干开发”的方式,代码一般直接提交到主干的头部,这样可以保证所有用户看到的都是同一份代码的最新版本。
“主干开发”确实避免了合并分支时的麻烦,因此像 Google 这样的公司一般就不采用分支开发,分支只用来发布。
主干开发的优缺点如表 1 所示。
特性分支开发
Git Flow
Git 刚出来的那些年,可参考的模型不多,所以 Git Flow 模型在 2011 年左右被大家当作了推荐的分支模型,至今也还有项目团队在使用。然而,Git Flow 烦琐的流程也被许多研发团队吐槽,大家普遍认为 hotfix 和 release 分支显得多余,平时都不会去用。
- master: 主分支,主要用来版本发布,存放的应该是随时可供在生产环境中部署的代码。当开发活动告一段落,产生了一份新的可供部署的代码时,master分支上的代码会被更新。同时,每一次更新,都有对应的版本号标签(TAG)。
- develop:日常开发分支,该分支正常保存了开发的最新代码。develop分支上所有功能通过测试且代码已经足够稳定后,就可以将所有的开发成果合并回master分支了。对于master分支上的新提交的代码建议都打上一个新的版本号标签(TAG),供后续代码跟踪使用。
- feature:具体的功能开发分支,只与 develop 分支交互。
- release:release 分支可以认为是 master 分支的未测试版。比如说某一期的功能全部开发完成,那么就将 develop 分支合并到 release 分支,测试没有问题并且到了发布日期就合并到 master 分支,进行发布。
- hotfix:线上 bug 修复分支。
GitHub Flow
GitHub Flow 是 GitHub 所使用的一种简单流程。该流程只使用 master 和特性分支,并借助 GitHub 的 pull request 功能。
在 GitHub Flow 中,master 分支中包含稳定的代码,它已经或即将被部署到生产环境。任何开发人员都不允许把未测试或未审查的代码直接提交到 master 分支。对代码的任何修改,包括 Bug 修复、热修复、新功能开发等都在单独的分支中进行。不管是一行代码的小改动,还是需要几个星期开发的新功能,都采用同样的方式来管理。
当需要修改时,从 master 分支创建一个新的分支,所有相关的代码修改都在新分支中进行。开发人员可以自由地提交代码和提交到远程仓库。
当新分支中的代码全部完成之后,通过 GitHub 提交一个新的 pull request。团队中的其他人员会对代码进行审查,提出相关的修改意见。由持续集成服务器(如 Jenkins)对新分支进行自动化测试。当代码通过自动化测试和代码审查之后,该分支的代码被合并到 master 分支。再从 master 分支部署到生产环境。GitHub Flow 的好处在于非常简单实用,开发人员需要注意的事项非常少,很容易形成习惯。当需要修改时,只要从 master 分支创建新分支,完成之后通过 pull request 和相关的代码审查,合并回 master 分支就可以了。
GitLab Flow
GitLab Flow 针对不同的发布场景,在 GitHub Flow(特性分支加 master 分支)的基础上做了改良,额外衍生出了三个子类模型,如表 2 所示
特性分支优缺点:
国内互联网公司的选择
GitLab 作为最优秀的开源代码平台,被多数互联网大公司(包括阿里、携程和美团点评等)所使用,这些大厂也都采用特性分支开发策略。当然,这些大公司在长期持续交付实践中,会结合各自公司的情况做个性化的定制。
比如,携程公司在 GitHub Flow 的基础上,通过自行研发的集成加速器(Light Merge)和持续交付 Paas 平台,一起完成集成和发布。再比如,阿里的 AoneFlow,采用的是主干分支、特性分支和发布分支三种分支类型,再加上自行研发的 Aone 协同平台,实现持续交付。
总结
代码扫描
集成Sonarqube、支持了所有主流的编程语言。
单元测试
整合了Java中常用的Jacoco工具,方便用户在运行单元测试时,生成对应的UT和覆盖率报告。
代码编译
Maven/Gradle/Ant,并且内置了Nexus私服、Node.js支持了Npm;Golang支持了go mod缓存加速。
镜像构建
支持Docker out of Docker、Kaniko两种构建方式,用户可以根据自身需求、构建后上传harbor或者阿里云仓库。
部署/容器部署
支持kubectl原生部署、升级,以及应用部署等多种部署方式。
自动化测试
支持Java语言常用的TestNG,同时需要整合公司自动化测试平台(自动化脚本/后续开发平台),支持在流水线中运行指定的接口测试集,并在执行时输出测试报告。
告警通知
- 上线提示
- 故障提示
- 测试人员点击链接发布测试环境
实现方式:
- 接入监控报警服务
- 报警群分组(生产、测试、开发)
- 钉钉报警
服务部署
延展
敏捷交付挑战
- 多个技术栈;
- 多个不同类型的应用;
- 不同的开发环境和运行环境。
传统交付方法,已经很难满足这样快速迭代的交付需求,服务交付方式、快速部署、环境隔离、环境一致性等诸多问题亟待解决
容器技术
重新定义交付标准:没有容器前,交付主要关注软件代码,对应软件环境(也就是所谓机器)的变更没有版本、没有记录。而容器技术统一了软件环境和代码。
-
交付结果一致
任何变化,包括代码、环境、配置的变更,都需要重新制作镜像,产生一个新的版本。在不同运行环境下发布都基于新的镜像
-
交付自动化
容器镜像及容器编排技术很好地解决了 CI 和 CD 问题:
-
CI 方面,与传统方式的不同只在于,原先交付的是安装包或软件包,而容器交付的则是镜像;
-
CD 方面,与传统方式相比则有了长足的进步。对传统方式而言,部署和安装方式与软件类型、开发方式有直接关系,存在多种多样的可能。而容器技术则没有这样的问题,唯一的方式就是拉起容器镜像。这就大大简化了部署的复杂度,而且在编排系统的支持下,完成 CD 越来越容易了。
-
容器化之前准备工作
-
日志规范化(落盘路径、大小、收集方式等)
-
日志可视化(线上系统error、debug、warn等日志查看)
-
各环境参数切换(配置中心)
…