本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2018年05月14日 统计字数: 3466字 阅读时间: 7分钟阅读 本文链接: https://soulteary.com/2018/05/14/ci-cd-practical-experience.html ----- # 闲聊 CI/CD:回顾折腾史 计划给内部好好写一篇CICD相关的博客,详细聊聊CI过程中可以玩的有意思的东西,先整理回顾一下之前的事情。 ## 第一次亲密接触 第一次非正式接触 CI (Continuous Integration) 是在公司内部。 有人用一台虚拟机搭建了 Jenkins 来“联动”代码提交,进行前端自动构建,还记得要填写一堆配置脚本,每个脚本里还有一些写死的配置项(**当时缺少配置服务平台**),更新起来比较麻烦,起码要修改两处,在项目初期偶有修改项目结构的场景下,很多时候宁愿手动。 ## 定制化的云端构建 后边团队有了云端统一构建服务,CI 功能集成到统一的“开发服务器”上,一方面构建环境的差异得到了有效抹平,另一方面,有了自动化过程,大家开始逐步添加核心逻辑的测试代码,以及开始顺手跑一下诸如 `jshint`、`jslint` 之类的质量工具,线上构建结果、线下代码质量都有了一定的保障。 ## 开源项目标配 与此同时,15年不经意之间接触到了 `travis-ci` ,惊叹原来 CI 工具的体验原来可以是这样的。 极少的配置,通用的阶段描述,剩下的都由工具来做,而且除了定制 Runtime ,还能够定制执行系统,对于想做跨平台开发的人,非常友好:构建环境和构建产物可以一致、稳定。 翻到当时的一个集成构建记录:[jquery-city-select](https://travis-ci.org/soulteary/jquery-city-select) ,展示了使用不同 Node 0.10、0.12、iojs 分别对一个前端组件进行构建。 ## 尝试第一次折腾 可能是出于对自动化的着迷,当时特别想拥有一套自己的开发环境,居然还跑去知乎还提了一个问题:[你理想中的前端开发环境是怎么样的?现在使用的方式有什么缺点?](https://www.zhihu.com/question/27961588)。 后面实在忍不住,折腾了一个demo,基于虚拟机的跨平台开发环境,包含了前端的自动构建。[https://github.com/Pantimos](https://github.com/Pantimos) 把下面提到的问题解决了一大半: ```plain 欢迎讨论和补充甚至广告,但是请简要说明: 大概想到以下场景: ❶ 单人开发完整项目。 ❷ 单人开发组件模块。 ❸ 多个前端协同开发业务模块。 ❹ 前后端一起开发以及联调,以及冒烟前的自测。 ❺ 离线开发,不强依赖线上服务。 ❻ 评审等时候的临时显示需求。 ❼ 多个不同环境依赖的项目同时进行。(update) ❽ 项目前后端不完全分离。 大家面对以上情况时候,在使用以及期望的理想环境是如何的? 补充问题: ① 考虑多人协作操作系统文件编码可能产生不一致,多人本地使用工具构建结果可能产生不一致的问题(不涉及编码风格),中心机构建有时不利于日常/线上调试的问题。 ② 考虑非发布以及bugfixs,必须进行版本控制提交时候的开发(试验性质测试以及开发过程中的状态)。 ③ 考虑后端童鞋可能接手简单的前端项目的开发或者调试时候的使用,但是不愿意去尝试复杂的前端发布流程。 ④ 多个不同环境依赖的项目同时进行时,本地开发时因为使用的代理软件和语言runtime版本和线上不一致,或者不便模拟线上环境的时候,得到的相似(不是近似)环境可能带来的影响。 ⑤ 本地虚拟化服务来在某些时刻替代中心机服务,是否对于本地开发过重,如果本地虚拟化可以比较完善的解决上面的问题,那么值得使用么。 ``` 然而`离线`不是必选,尤其是随着网络基础设施的进化,网络质量越来越好是大趋势,交付效率的提升、交付质量的提高之外,更应该关注协同效率。 ## 尝试第二次折腾 随后来到美团,团队起步阶段想做各种 MVP Demo,发现公司内部缺少 PaaS (新浪云不要太爽),构建过程缺少CI(淘宝不要太爽),开发时感觉十分痛苦,忍耐着使用了本地起Nginx、开发服务器同步本地构建产物等一次性方案解决了这个问题。 不久之后,看到有一个前端的小伙伴做了一套山寨的 `Travis CI`,但是好像只支持按照一定特殊使用规范下的项目接入,能用但是感觉不够好用,这个显然不是我想要的自动化工具。 随后技术工程部入职了一位来自 Google 的大神,海波大神想要重新打造一套先进的基础设施,包含代码仓库、持续集成、运行环境等。其中持续集成便是基于 docker 的容器化excuter ,可以看做特异化的 `compose`,这个是我想要的,但是和公司特殊场景耦合太重,自己想做一个小东西的时候,太麻烦了。 短暂思考之后,发现这这个设施应该是极度贴近代码仓库,那解决方案也就呼之欲出了:支持WebHook的代码仓库+WebHook+docker-compose,实验过程产物[common-webhook-template](https://github.com/soulteary/common-webhook-template)。 ## 围绕代码仓库进行的自动化 ### WebHook Jira、GitHub、GitLab等软件的功能是不同的,故实现标准也是不同的,需要额外维护数据接入层,比较麻烦。 最好是能够使用官方维护的推荐工具,诸如:GitLab-Runner。 ### 构建过程 最开始使用过WebHook调用远程服务器脚本,诸如: - openresty+none-block sock - PHP等语言提供的system调用等 但是随着接入项目一多,尤其是跨语言的项目多了之后,维护构建脚本十分麻烦,比如初始化PHP fpm、HHVM cgi、node.js+pm2、Java Jetty完全不是一个套路,后面有新的技术栈的时候,这个构建脚本就得多一套。 然后尝试把这类东西打包成docker fat镜像,(docker当虚拟机用),发现几个额外的问题: - 镜像基础环境更新,性能提升或者安全补丁修正,是必要重打一次完整镜像。 - 基础运行代码打到镜像里,频繁改动的时候,镜像也得重构建,浪费时间,浪费资源。 - 镜像里的应用进程得自己进行维护,而且要把每个镜像维护出一个foreground running的进程。 - 涉及到应用之间交换数据的时候,除非靠母鸡起一个网关交换流量,不然维护起来也很麻烦。 然后接触到了compose,从1.x开始,到2.x,再到现在的3.x,功能越来越强大,(docker + compose)性能也越来越好。 从使用 `docker-compose up`,使用回调方案异步告知构建过程结束,到配置文件定义机器资源配置,直接使用`docker-compose run`同步等待构建结果完成,中间的折腾也是不足为外人道了。 ## 内外差异 ### 内部CI系统的标杆 GitLab是一个好软件,盘点了一下,基本贯穿了正式工作以来的多数公司: - 新浪云12还是13年就把SVN迁移成了Git,使用GitLab进行代码管理,个人同一时间开始使用虚拟机跑GitLab的方案折腾一些小东西。 - 淘宝从14年开始,逐步把SVN迁移到了Git,使用GitLab进行代码管理; - 美团记忆中好像还是jira的那套,不太确定了,个人开始使用dockerize GitLab继续折腾。 - 阿里云也是14年开始就在使用Git了,使用GitLab进行代码管理。 - 小赢好像是在我来到之前,就迁移了Git,使用GitLab进行代码管理。 对于团队,或者对于家里有机柜的同学来说,起步4G的内存没什么,随便一台老笔记本、老服务器、mini NAS都能跑的起来。 但是如果你有公网需求,代码又是介于公开和私有状态的半成品,但是又要联动 CI,想要进行自动化构建,跑基于构建结果的定时任务... 公网跑一台2C4G的云服务器,还是比较奢侈的,要知道虚拟CPU的云服务器,尤其是国内服务器,除了带宽,贵就贵在“储存”上,这里可以使用秒级付费的产品,但是构建实时性势必又有妥协了。 ### 外部CI系统轻量 那么,不如稍稍差异化,在构建方案保持使用 docker 容器进行执行,严格保障构建环境一致的原则下,替换掉重型的GitLab+GitLab Runner: - 使用 GitHub(考虑敏感性可以使用 GH 私仓)或者自建 gogs 进行代码托管。 - 使用 Drone 进行简单的 CI 集成。 目前除了不好实现并发的任务过程,文档存在一些缺失,实际使用要偶尔翻一下源码,总体来说体验还是不错的。 ## 后续 稀稀疏疏地按照时间线展开了不少内容,后面有机会再补充一些其他的吧: - CI 过程的流程分层设计 - CI 过程的数据敏感处理 - CI 过程的构建产物贮存 暂时搁笔。 --EOF