为什么大型工程团队要在 Kubernetes 上进行测试?
将来,开发人员应该如何处理生产应用程序呢?是应该将本地的生产环境复制到云,还是应该直接在云环境中编写和运行所有代码,或者采用介于二者之间的某种方式?
原文链接:https://www.signadot.com/blog/large-engineering-teams-testing-on-k8s/
未经允许,禁止转载!
简介
在过去的几年里,我们看到很多开发团队从纯粹的本地开发转向基于云的开发环境。目标是提高开发速度,并控制无法完美复制环境的问题。
在本文中,我们来看看一些企业团队的解决方案。
在谈论开发人员在哪里编写新代码时,我们经常提及他们“测试”代码。这里的“测试”指的是自动化单元测试或端到端测试之前的一个阶段,开发人员需要在这个阶段研究如何让代码与其他资源交互。在测试驱动开发中,这两个阶段可能没有明显的区分。在本文中,为了简洁起见,我们将统一使用“测试”,尽管这个词本身还包括单独的一个部署后期阶段。
利用微服务提升开发速度
在尝试与四个不同的企业工程团队交流后,我发现他们的故事有很多相似之处,所以在此我将他们合并成一个故事。值得注意的是,不仅他们的最终结论非常相似,而且每个团队在确定基于云的开发环境之前都尝试了类似的解决方案。
我研究的案例有 Lyft、Reddit、Doordash、Eventbrite 和 Prezi。虽然并非所有团队最终都选择使用共享的 Kubernetes 集群,但他们都试图用类似的方法解决类似的问题,而且都面临着共同的困难。
成本与收益
在考虑改变开发人员的环境时,我们要考虑的一个关键问题是:在开发陷入停滞之前,如何确定投入精力对开发工作流程进行重大改革是否值得?
为此,Eventbrite 团队在一篇文章中讨论了这个决策,标题是:“为什么我们的开发环境运行了一个700个节点的K8s集群?”首当其冲必须考虑的不利因素是:通过共享集群来测试代码时,工具和集群的开发时间以及维护成本都会增加。
关于在共享 K8s 集群上进行测试,Eventbrite 提到了如下好处:
你是否曾听开发人员说:“在我本地运行测试时完全没问题”。在云中运行测试可以提高一致性。事实证明,在探究测试失败的原因或解决难以重现的问题时,共享开发人员环境能给予极大的帮助。
这是在共享集群上进行测试的核心优势:更早地发现未知的未知数,并永久消除可怕的一个常见问题:“在我机器上没问题。”
第一阶段:每位开发者都是一座孤岛
为了方便开发人员搭建环境,Prezi 等团队提供了服务安装、测试以及运行等方面的hook脚本。他们的工具还可以管理服务间通信。但是,由于每位开发者机器的独特性,hook脚本经常会因为依赖冲突而运行失败。工程师们花了很多时间来解决这些问题,但在几个月后重新访问服务时还是会遇到新的问题。
这种不一致的问题是大型开发团队没有同步所有依赖项的必然结果。通常这种不一致在经过长时间的调试后才会显现出来。
第二阶段:Docker Compose
当谈论使用容器化工具共享开发环境时,大多数人都会想到Docker。通过容器化所有依赖项并使用 Docker Compose 进行编排,就可以强制开发人员每天同步依赖项。与第一阶段相比,这种方法的巨大优势在于,无需等到失败才意识到你的环境需要更新。
最大的缺点是,很快你就会发现自己的 macbook 烫手。
每天下载新的容器并重新构建,只为了尝试一些开发上的小改动,这会极大地影响开发人员的速度。
Docker Compose 的问题在于,它的成本通常是隐藏的,你的笔记本电脑由于运行复杂的工作负载而停滞,因此而造成的时间浪费都无法明确地记入损失。也许每个小时它都会时窃取 10 分钟。但这不会成为阻止我们在一个月内发布新功能的障碍,结果导致你必须承担所有压力,在截止日期之前完成工作。
为了解决本地机器资源有限的问题,我们可以在云中提供虚拟机, 并在其中运行 docker compose。然而,当服务和相关数据库等的数量超过 15~20 时,这类系统将变得难以管理。
对于 Reddit 团队,此问题已被确定为已知限制。他们开发了一个自定义工具来最大程度地减少重建和重新下载,以尽量减少每天的启动时间,并迁移到 kubernetes 集群以共享开发人员进行试验时所需的大部分资源。他们为此开发了一个名为Tilt的工具进行管理。如果你的团队有足够的资源,不仅可以改变开发环境流程,还可以维护内部工具,那就可以考虑采用这种方式大幅缩短每天早上的构建时间。
第三阶段:Kubernetes 上的远程环境
在 Kubernetes 之上构建远程环境,这样开发人员的代码和依赖项由开发者体验团队集中管理,而开发人员的电脑上只需运行一个轻量级命令行工具和几个库。
Eventbrite采用的方式与之类似,他们使用了一个名为 yak 的自定义工具来处理开发人员代码和共享集群之间的交互。yak 还有一个巨大的好处是可以方便开发人员体验Kubernetes:
我们尽可能保持集群最小化,配置文件就是普通的 Kubernetes 清单文件。目的是满足开发人员的好奇心,以便他们逐步了解更多关于 Kubernetes 的知识。
这种“轻量级”的交互可以为团队带来舒适感,逐步过渡到开发运维。
如何与共享集群交互
与共享集群的交互有两种模式:有些人希望与其他团队的工作状态完美同步;而有些人则希望能够根据自己的设计进行修改。
图片源自 Reddit Eng 博客,展示了大多数资源的共享方式,而且不会受开发人员实验的影响。
在 Prezi,开发人员可以自由地在自己的沙箱(Kubernetes 命名空间)中进行试验,而且可以通过两种不同的模式运行服务:
●依赖模式:在这种情况下,工具需要提供一组特定的服务,并使用 Helm 和 Helmfile 简单地部署依赖项的预构建和预优化容器。
●开发模式:这种模式适合正在积极开发的服务。我们使用 Skaffold 构建图像并同步更改,以便开发人员快速查看修改结果并获得反馈。
一般而言,你需要设置“待测”服务和剩余的“稳定依赖项”。依赖关系可以按需启动,就像基于命名空间的方法一样;或者依赖关系始终存在并通过 CI/CD 工作流不断更新的共享层来满足依赖关系,就像请求路由一样。
如果我不想构建自己的工具,该怎么办?
以上所有这些案例都涉及内部开发人员体验团队维护的工具。这种开发者体验的成本不容小觑,而且我们也不得不思考这样一个问题:“为什么没有适用于这种模型的 SaaS 解决方案?”
Signadot 就是这类的一款 SaaS 工具,可以帮助你共享 Kubernetes 集群并仅在你关心的服务上进行实验。
两名开发人员可以同时使用共享的开发集群。环境不需要模拟,而且运营团队只需维护一个开发集群。
Signadot 绝不是通过开源工具共享开发集群的唯一方式,但它可以处理一些困难的边缘情况,例如服务之间的请求路由,从而降低了多个开发人员共享一个开发集群的难度。
推荐阅读:
▶小米辟谣武汉总部35岁以上员工只保留10%;丰田致歉!200万车主车辆数据遭泄露;jQuery 3.7.0 发布|极客头条
▶突发!OPPO 关停“造芯”业务 ZEKU:近 3000 名员工“原地失业”,赔偿 N+3