这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
导入
自2015年以来,微服务就已经在各种不同规模的科技公司中生根发芽,变成一种流行,仿佛一夜之间由大单体时代就进入了微服务时代。伴随着容器技术以及容器编排技术的成熟和统一,微服务进入了云上的新阶段。微服务的数量越来越多,分布式耦合变得也越来越紧,这就为研发、测试、发布提出了新的挑战。在容器和Kubernetes的加持之下,测试和发布几乎得到了圆满的解决,CI/CD领域几乎是瓜熟蒂落。可是对于开发人员来说,还依然两脚站在泥潭里,怎么快速在本地构建一套完整的开发环境呢?如何与依赖的其他服务进行联调呢?
本地开发模式
本地开发是所有后端开发同学都十分熟悉的模式,特别是在单体时代,所有程序都在本地,包括依赖的数据库、缓存、入口代理等等,只要启动起来本地就可以做一切的操作了,可调试、可测试、可联调。
云原生时代
进入云原生时代后,容器和Kubernetes附以CI/CD流程工具完美实现了代码提交后的持续集成,持续部署,大大提升了部署和运维的执行效率。可是还有一个环节,dev并没有被照耀到,反而变得更加艰难了。按照目前的流程,一行代码修改后到可以看到执行效果,最坏需要经历代码提交、单元测试、代码编译或打包、镜像编译、镜像推送、服务部署@测试环境、执行测试。如果repo比较大,可以看到这将是一个极其漫长的过程,可以去喝一杯咖啡了。
为了解决这个问题,现在业界也提出了一些解决方案,我们先来了解一下,然后再提出我的想法供大家参考。
业界方案速览
dev@本地
docker compose
在Kubernetes早期,docker推出了compose来与之进行抗衡,事实证明谷歌的Kubernetes更胜一筹,但是docker compose对于本地环境构建来说也有其突出的地方。
在研发交付阶段交付的实际是镜像,因此在本地执行与在远端Kubernetes中执行是没有本质区别的。因此在本地环境中,也可以通过docker compose来搭建研发测试环境。
在团队规模不大,服务的数量不多的情况下,docker compose是非常方便和高效的。据笔者观察,曾见过一个案例团队规模将近百人,微服务数量不超过20个,就是使用的docker compose来搭建的各个本地开发环境,甚至测试团队也是在本地通过这种方式进行测试。
然而随着团队规模的扩大,这种方式的弊端也越来越明显,成员在环境上浪费的时间也越来越多,特别是不同成员之间环境的一致性问题,反复困扰着整个团队。一个有经验的新成员加入,至少也需要两天的时间来搞定研发环境,成本不可谓不高。
本地与云端打通
为了重复发挥云端的优势,一个直观的思路就是将本地与云端进行打通。
注:图片来自文章3,侵删
如何将两端进行打通,以及与当前工具链进行整合的程度,催生了当前社区的不同工具。
telepresence
telepresence目前是CNCF基金会下的项目,官方的介绍是这样的:
Telepresence gives developers infinite scale development environments for Kubernetes. With Telepresence:
- You run one service locally, using your favorite IDE and other tools
- You run the rest of your application in the cloud, where there is unlimited memory and compute
This gives developers:
- a fast local dev loop, with no waiting for a container build / push / deploy
- ability to use their favorite local tools (IDE, debugger, etc.)
- ability to run large-scale applications that can't run locally
简单翻译一下就是,使用Telepresence,你可以使用你喜欢的IDE或者其他工具在本地启动一个服务,并且可以在云端运行其他的应用,好处是实现快速的本地开发回路,不需要再等待容器的构建、推送、部署了,当然还有一些其他的好处。
实现原理
Telepresence基本是一个本地代理,通过在Kubernetes集群中业务的POD中部署双向网络代理,将远端的数据卷、环境变量、网络都代理到了本地进程。本地进程的网络被透明覆盖,因此DNS和TCP连接通过代理路由到远端的Kubernetes集群中。该机制实现了:
- 本地服务可以完全访问远端集群中的其他服务
- 本地服务也可以访问到Kubernetes集群中的环境变量、configmap、secrets等配置信息
- 远程集群中其他服务也可以访问到本地服务
关键技术点
- DNS查询 依赖sshuttle的能力,默认开启 --method vpn-tcp 使用ssh连接建立数据包的隧道。
- 网络透明覆盖 依赖Linux/OSX的动态调用劫持机制,将共享库覆盖原库调用,实现将所有网络请求路由到集群
nocalhost
nocalhost是腾讯系的全资子公司发布的开源解决方案,目前也纳入到了CNCF进行管理。背靠腾讯,该工具提供了更为全面的功能,支持丰富的IDE种类,对主流编程语言也有很好的支持,当然更可以满足本地开发调试的需求。
实现原理
nocalhost本质上并不是本地运行的,只是在本地完成代码输入,IDE插件会将代码发送到远端,并通过在远端POD中注入一个开发调试容器来运行刚才的代码。
详细可以参考其官方文档,这里不再详细展开。
ACT(Alibaba Cloud Toolkit)
ACT来自阿里云的产品工具包,目前看已经支持其核心云产品,使用阿里云的可以参考一下,目测功能非常强大,不仅仅支持本地与云端的网络打通,更支持了多人精确测试、远程调试等。可以参考文档3。声明无利益相关,纯技术推荐。
Kt Connect
Kt Connect是阿里巴巴开源的一款协同开发测试的工具。目前的功能包括:
- 直接访问 Kubernetes 集群
- 转发集群流量到本地
- Service Mesh 支持
- 基于 SSH 的轻量级 VPN 网络
- 作为 kubectl 插件,集成到 Kubectl
实现原理
Kt并没有完全重复造轮子,而是充分利用了sshutle来实现网络代理,限于篇幅这里先不详细介绍,感兴趣的可以先看一下参考文档5.
小结
以上几种方案几乎都有一个共同的前提,就是需要拥有访问Kubernetes集群的权限。这一点在人员相对比较少的团队可能没有太大问题,权限管理起来也不是很复杂,但是如果是比较大的团队,上百人之后就有些不现实了。实现一种不依赖于Kubernetes集群直接访问权限的方案就变得很有价值。这也是本次我要提出的解决思路的重点,下一篇文中我们再详谈。
dev@云端
前面我们说了两种实现思路,一种完全在本地,另外一种比较大众化是实现本地与远端的网络打通,其实还有一种比较开脑洞的思路就是开发也完全在远端。这样的好处是完全没有本地什么事情了,也从网络打通也没有任何必要了,因为开发和运行都在远端环境中。这有点类似远程桌面,本地只是一个瘦终端,代码的存储和运行都不在本地。这个思路来自参考文档8,可以说也有一定的参考价值。
一般来说,没有完美的方案,凡事都会有利有弊。开发和运行都在云端确实省去了打通本地和远端网络环境的困难,但是远端开发桌面也是一个很吃资源的系统,特别是带IDE的开发环境。需要企业采购一整套的虚拟桌面服务来保证研发人员可以流畅的使用。除去硬件资源的投入,这种现成的实现工具目前在业界也并不存在还需要自行去摸索开发。因此只当做给大家开阔一下思路列在这里,不做重点推荐。
总结
本文中我们总结了当前解决在云原生的环境下,如何实现高效的本地开发调试。业界给出了几个比较优秀的解决方案,同时也有可用的配套工具。当然也有一些不可回避的约束,例如需要直接访问Kubernetes集群,这在一些非常注重集群安全的公司是很小心的(注意:这跟连接到POD内部不是一个概念),管理成本不容小觑。在下一篇文章中我将给大家分享我是如何解决这个问题的,敬请期待~
参考文档
3、ACT介绍 baijiahao.baidu.com/s?id=169944…
4、Kt Connect介绍 developer.aliyun.com/article/751…
5、Kt Connect原理介绍 vearne.cc/archives/39…
6、telepresence介绍 blog.betacat.io/post/develo… 注意:该文中版本比较早期,现在已经进入telepresence2时代,并且已经用go重写了,对第一代进行了重大更新,可参考官方文档