背景
在我们开发实际产品的过程中,最普遍的一个需求就是如何快速的构建属于自己的测试,开发环境。多开发,多测试环境的方案纷繁多样,如何选择一条适合自身产品,自身团队的技术栈十分重要。
历史
我们所要解决的问题本质其实就是前些年大火的 DevOps 概念中的一个层面。DevOps 起源历史悠久,最早可追溯到 2007年的比利时独立咨询师 Patrick Debois,他当年从事的政府项目时,需要频繁和开发团队,运维团队打交道,遇到了一些列的问题促使其思考如何让协助更加敏捷,工作高效。
2009 年 Flickr 公司的 John Allspaw 和 Paul Hammond 发表的一场关于 ““10 Deploys per Day: Dev and Ops Cooperation at Flickr” 演讲引发了对于研发和运维目标一致相互协作的新观点,这场演讲也进而推动了Debois 举办了一个名为 DevOpsDays的大会,这场大会至此让 DevOps 正式走上历史舞台。
追本溯源,我们知道前人们在 DevOps 演进中,引入了敏捷,自动化,精益,目标协作等形而上学方法论的东西,无非是为了解决和满足系统随时上线,协作整体效率提升的痛点,既然大的痛点我们各有体会,那么说说一下我们自身业务需要解决的痛点主要是什么。
痛点
多环境部署的几个刚性需求无外乎如下几个:
- 自助化接入,接入流程简单
- CI,CD 流水线支持,基本的权限管理
- 环境尽量隔离,相互开发测试互不影响
- 随时可以测试验证新功能,编译,部署效率高
关于 CI/CD 和 DevOps 的区别和联系,可以参考 https://www.quora.com/What-is-CI-CD-in-DevOps 这篇问答中的几张图片来体会一下。
业界方案
知道了痛点,问题就变得越发清晰了,就如同知道了为什么,才能更好地想怎么做。在实际实施前,我们先看看业界目前的玩法都有什么,有什么值得我们学习和借鉴的。
CI/CD 开源: Jenkins, Jenkins X, Gitlab CI/CD,Spinnaker, Travis CI,Github Actions 等
CI/CD 云厂商和公司:
CircleCI,Cloud bees CodeShip, Drone
AWS CodePipeline,Google Cloud Build,Azure Pipelines ,腾讯云 Coding DevOps
综合 CI/CD 的工具的特点我们可以发现几个特点:
- 基于云的 CI/CD 方案趋势化
- 私有化的 CI/CD 方案支持
- 面向云原生系统的 CI/CD 支持
公司方案
公司的 DevOps 类似织云等工具,在内部有着广泛的用户,承载了很多流程上的一些可以快速利用的能力,借助这些能力实现开发,测试的快速验证,快速部署,对于整体的研发效率提升都有着很大的帮助。
考虑环境中对现有的共有域名的重用,所以设计依靠路由转发,这种方案本身也支持前后端使用各自的代码分支进行发布测试,选取了一种如下的 Devops 自助开发环境:
选取架构
上面的自助方案也有一些缺点:非完全独立环境,依赖的一些第三方回调接口没有完全隔离。 在架构实施过程中,我们也遇到了其他的问题,对于这些问题给出了一些相应的处理方式:
- 镜像是否包含应用依赖的 agent,比如名字解析服务等基础的 agent
目前有公有镜像,自己维护私有镜像(打包 agent 方式),DameonSet(独占集群场景)
- TKE 支持 CLS 日志方式和传统的 VM 上 loglistener agent 结果差异
如果应用之前集成过 CLS API 调用,可能需要代码适配调整
- 日志存储 volume 对于 CBS 支持是否灵活
暂时采用类似 hostPath 方式
- TKE 和 VM 跨地域配置下的通信延迟问题
程序优化,和集群调整部署,远程一些依赖进行容器化
- 对外开通 80, 443, 其他端口暂时无法直接访问
VPC 内网访问内网 Nginx 转发
遗留问题
- 共享数据的冲突
多个独立环境,共用一套 db 配置,可能引起不同进程更新共享数据的问题
- 底层回调依赖问题
目前一些依赖的第三方回调都是配置的线上回调,第三方没有很好的机制支持动态注入其他信息,无法确切知道是
哪个开发环境调试触发,因此很难转发到对应的 service IP
- 集群日志的隔离
因为集群日志的接入是独立的,所以需要各自的日志主题配置
- 其他共享数据问题
共享的分布式 k-v 数据库,MQ 配置等
解决方案
方案1 - 减少数据依赖,独立数据方式
- 优点: 隔离性,安全性好
- 缺点:成本大 (硬件,或者软件方案)
如果不考虑硬件共享问题,随着泛化上云的普及,这种方式应该是更偏向完美
方案2 - 优先主要程序隔离(2,8 原则),减少不重要进程依赖
- 优点:关注主要精力类似主应用服务器的隔离开发
- 缺点: 其他进程共享方式,如果单独开发调试支持有难度
方案 3 - 减少底层依赖,增加 Mock 支持
如果底层可以根据 SDK 开发,确认是否有相应的测试模拟工具支撑
- 优点: 可以任意模拟支持底层依赖
- 缺点: 引入新的协议变更,需要同步修改模拟工具,增加了一定程度的维护成本
方案 4 - 增加特性开关支持
- 优点:特性开关方式,可以减少其他开发者因为共享数据导致的问题
- 缺点:大部分修改,没有独立的修改部分,特性开关不太现实
短期看,方案 2 成本小,长期看,方案3 ,方案 4 较灵活,方案1 偏向完美,但是成本稍高
参考
1. https://en.wikipedia.org/wiki/DevOps
2. https://devops.com/the-origins-of-devops-whats-in-a-name/
3. https://insights.thoughtworks.cn/instantiate-the-principles-of-devops/
4. https://www.quora.com/What-is-CI-CD-in-DevOps