(2021)不必要的复杂性如何给服务网带来恶名

服务网格具有巨大的价值,但它必须以轻量级的方式完成,以避免不必要的复杂性。

内容出处

How Unnecessary Complexity Gave the Service Mesh a Bad Name

https://www.infoq.com/articles/service-mesh-unnecessary-complexity

作者 Chris Campbell 发表于 2021年2月25日

低复杂度 - 服务网格的下一站

https://atbug.com/service-mesh-unnecessary-complexity/

翻译 张晓辉


译者:

作为一个曾经在制造业企业的基础架构团队任职,为支持公司的“互联网基因”和“数字化转型”落地了云原生基础设施平台,并在尝试采用服务网格未成的我来说,看到这篇文章深有感触。尤其是文中所说的“人少,问题多,需要快速输出价值”,直戳到了痛处。有限的人手有限的时间,我们需要将大部分精力集中在解决成熟度曲线较低的基本问题上,要想很好的运行复杂的系统是非常困难的。

服务网格是一个新的基础设施层,可以承载很多的功能,未来还会有更大的想象空间和光明的未来。

以上的种种原因,也促使我后来选择进入一家提供服务网格的产品企业,也希望服务网格可以被更简单的使用。

“道阻且长,行则将至!”

本文翻译自 Chris Campbell 的 How Unnecessary Complexity Gave the Service Mesh a Bad Name


关键要点

  • 采用服务网格有巨大的价值,但必须以轻量级的方式进行,以避免不必要的复杂性。
  • 在实施服务网时,要采取务实的方法,与技术的核心功能保持一致,并小心干扰(译者:注意力的分散)。
  • 服务网格的一些核心特性包括标准化监控、自动加密和身份识别、智能路由、可靠的重试和网络可扩展性。
  • 服务网格可以提供强大的功能,但这些功能会分散本应对核心优势的关注,并且这些功能也不是实施服务网格的主要原因。
  • 在初始实施服务网格时没有必要去关注那些明显会分散注意力的功能,比如复杂的控制平面、多集群支持、Envoy、WASM 和 A/B 测试。

服务网格是 Kubernetes 世界中的一个热门话题,但许多潜在的采用者已经有些失望了。服务网格的落地受到压倒性的复杂性和看似无穷无尽的供应商解决方案的限制。在我亲自浏览了这个领域之后,我发现采用服务网格具有巨大的价值,但它必须以轻量级的方式完成,以避免不必要的复杂性。尽管普遍存在幻灭感,但服务网格的未来依然光明。

在工作中学习

我进入服务网格的世界始于我在一家老牌的财富 500 强技术公司担任云计算架构师的角色。在开始我们的服务网格之旅时,我身边有许多强大的工程师,但大多数人几乎没有云计算开发经验。我们的组织诞生于云计算之前,完全实现云计算的价值需要时间。我们的传统业务线主要集中在技术栈的硬件元素上,云计算的决策最初是由为运送硬件或为该硬件提供固件和驱动程序而开发的流程驱动的。

随着该组织经历其“数字化转型”,它越来越依赖于提供高质量的软件服务,并逐渐开发出更好的方法。但作为云计算架构师,我仍在为优先考虑硬件的业务流程,以及具有不同技能、流程和信念的工程团队导航。随着时间的推移,我和我的团队在将 .NET 应用程序迁移到 Linux、采用 Docker、迁移到 AWS 以及与之相关的最佳实践(如持续集成、自动化部署、不可变基础设施、基础设施即代码、监控等)方面变得熟练并成功。但挑战依然存在。

在此期间,我们开始将我们的应用程序拆分为一组微服务。起初,这是一个缓慢的转变,但最终这种方法流行起来,开发人员开始更喜欢构建新的服务而不是添加到现有服务。我们这些基础设施团队的人把这看作是一种成功。唯一的问题是与网络相关的问题数量激增,开发人员正在向我们寻求答案,而我们还没有准备好有效地应对这种冲击。

服务网格的援救

我第一次听说服务网格是在 2015 年,当时我正在研究服务发现工具并寻找与 Consul 集成的简单方法。我喜欢将应用程序职责卸载到“sidecar”容器的想法,并找到了一些可以帮助做到这一点的工具。大约在这个时候,Docker 有一个叫做“链接”的功能,让你可以将两个应用程序放在一个共享的网络空间中,这样它们就可以通过 localhost 进行通信。此功能提供了类似于我们现在在 Kubernetes pod 中所拥有的体验:两个独立构建的服务可以在部署时进行组合以实现一些附加功能。

我总是抓住机会用简单的方案来解决大问题,因此这些新功能的力量立即打动了我。虽然这个工具是为了与 Consul 集成而构建的,但实际上,它可以做任何你想做的事情。这是我们拥有的基础设施层,可以用来一次为所有人解决问题。

这方面的一个具体例子出现在我们采用过程的早期。当时,我们正致力于跨不同服务的日志标准化输出。通过采用服务网格和这种新的设计模式,我们能够将我们的人的问题——让开发人员标准化他们的日志——换成技术问题——将所有流量传递给可以为他们记录日志的代理。这是我们团队向前迈出的重要一步。

我们对服务网格的实现非常务实,并且与该技术的核心功能非常吻合。然而,大部分营销炒作都集中在不太需要的边缘案例上,在评估服务网格是否适合你时,能够识别这些干扰是很重要的。

核心功能

服务网格可以提供的核心功能分为四个关键责任领域:可观察性、安全性、连接性和可靠性。这些功能包括:

标准化监控

我们取得的最大胜利之一,也是最容易采用的,是标准化监控。它的运营成本非常低,可以适应你使用的任何监控系统。它使组织能够捕获所有 HTTP 或 gRPC 指标,并以标准方式在整个系统中存储它们。这控制了复杂性并减轻了应用程序团队的负担,他们不再需要实现 Prometheus 指标端点或标准化日志格式。它还使用户能够公正地了解其应用程序的黄金信号

自动加密和身份识别

证书管理很难做好。如果一个组织还没有在这方面进行投入,他们应该找到一个网格来为他们做这件事。证书管理需要维护具有巨大安全隐患的复杂基础设施代码。相比之下,网格将能够与编排系统集成,以了解工作负载的身份,在需要时可以用来执行策略。这允许提供与 Calico 或 Cilium 等功能强大的 CNI 提供的安全态势相当或更好的安全态势。

智能路由

智能路由是另一个特性,它使网格能够在发送请求时“做正确的事”。场景包括:

  1. 使用延迟加权算法优化流量
  2. 拓扑感知路由以提高性能并降低成本
  3. 根据请求成功的可能性使请求超时
  4. 与编排系统集成以进行 IP 解析,而不是依赖 DNS
  5. 传输升级,例如 HTTP 到 HTTP/2

这些功能可能不会让普通人感到兴奋,但随着时间的推移,它们从根本上增加了价值

可靠的重试

在分布式系统中重试请求可能很麻烦,但是它几乎总是需要实现的。分布式系统通常会将一个客户端请求转换为更多下游请求,这意味着“尾巴”场景的可能性会大大增加,例如发生异常失败的请求。对此最简单的缓解措施是重试失败的请求。

困难来自于避免“重试风暴”或“重试 DDoS”,即当处于降级状态的系统触发重试、随着重试增加而增加负载并进一步降低性能时。天真的实现不会考虑这种情况,因为它可能需要与缓存或其他通信系统集成以了解是否值得执行重试。服务网格可以通过对整个系统允许的重试总数进行限制来实现这一点。网格还可以在这些重试发生时报告这些重试,可能会在你的用户注意到系统降级之前提醒你。

网络可扩展性

也许服务网格的最佳属性是它的可扩展性。它提供了额外的适应性层,以应对 IT 下一步投入的任何事情。Sidecar 代理的设计模式是另一个令人兴奋和强大的功能,即使它有时会被过度宣传和过度设计来做用户和技术人员还没有准备好的事情。虽然社区在等着看哪个服务网格“生出”,这反映了之前过度炒作的编排战争,但未来我们将不可避免地看到更多专门构建的网格,并且可能会有更多的最终用户构建自己的控制平面和代理以满足他们的场景。

服务网格干扰

平台或基础设施控制层的价值怎么强调都不为过。然而,在服务网格世界中,我了解到入门的一个主要的挑战是,服务网格解决的核心问题通常甚至不是大多数服务网格项目交流的焦点!

相反,来自服务网格项目的大部分交流都围绕着听起来很强大或令人兴奋但最终会让人分心的功能。这包括:

强(复)大(杂)的控制平面

要很好地运行复杂的软件是非常困难的。这就是为什么如此多的组织使用云计算来使用完全托管的服务来减轻这一点的原因。那么为什么服务网格项目会让我们负责操作如此复杂的系统呢?系统的复杂性不是资产,而是负债,但大多数项目都在吹捧它们的功能集和可配置性。

多集群支持

多集群现在是一个热门话题。最终,大多数团队将运行多个 Kubernetes 集群。但是多集群的主要痛点是你的 Kubernetes 管理的网络被切分。服务网格有助于解决这个 Kubernetes 横向扩展问题,但它最终并没有带来任何新的东西。是的,多集群支持是必要的,但它对服务网格的承诺被过度宣传了。

Envoy

Envoy 是一个很棒的工具,但它被作为某种标准介绍,这是有问题的。Envoy 是众多开箱即用的代理之一,你可以将其作为服务网格平台的基础。但是 Envoy 并没有什么内在的特别之处,使其成为正确的选择。采用 Envoy 会给你的组织带来一系列重要问题,包括:

  • 运行时成本和性能(所有这些过滤器加起来!)
  • 计算资源需求以及如何随负载扩展
  • 如何调试错误或意外行为
  • 你的网格如何与 Envoy 交互以及配置生命周期是什么
  • 运作成熟的时间(这可能比你预期的要长)

服务网格中代理的选择应该是一个实现细节,而不是产品要求。

WASM

我是 Web Assembly (WASM) 的忠实拥趸,已经成功地使用它在 Blazor 中构建前端应用程序。然而,WASM 作为定制服务网格代理行为的工具,让你处于获得一个全新的软件生命周期开销的境地,这与你现有的软件生命周期完全正交!如果你的组织还没有准备好构建、测试、部署、维护、监控、回滚和版本代码(影响通过其系统运行的每个请求),那么你还没有准备好使用 WASM。

A/B 测试

直到为时已晚,我才意识到 A/B 测试实际上是一个应用程序级别的问题。在基础设施层提供原语来实现它是很好的,但是没有简单的方法来完全自动化大多数组织需要的 A/B 测试水平。通常,应用程序需要定义独特的指标来定义测试的积极信号。如果组织想要在服务网格级别投入 A/B 测试,那么解决方案需要支持以下内容:

  1. 对部署和回滚的精细控制,因为它可能同时进行多个不同的“测试”
  2. 能够捕获系统知道的自定义指标并可以根据这些指标做出决策
  3. 根据请求的特征暴露对流量方向的控制,其中可能包括解析整个请求正文

这需要实现很多,没有哪个服务网格是开箱即用的。最终,我们的组织选择了网格之外的特征标记解决方案,其以最小的努力取得了巨大的成功。

我们在哪里结束

最终,我们面临的挑战并不是服务网格独有的。我们工作的组织有一系列限制条件,要求我们对解决的问题以及如何解决问题采取务实的态度。我们面临的问题包括:

  • 一个拥有大量不同技能的开发人员的大型组织
  • 云计算和 SaaS 能力普遍不成熟
  • 为非云计算软件优化的流程
  • 碎片化的软件工程方法和信念
  • 有限的资源
  • 激进的截止日期

简而言之,我们人少,问题多,需要快速输出价值。我们必须支持主要不是 Web 或云计算的开发者,我们需要扩大规模以支持有不同方法和流程的大型工程组织来做云计算。我们需要将大部分精力集中在解决成熟度曲线较低的基本问题上。

最后,当面对我们自己的服务网格决策时,我们决定建立在 Linkerd 服务网格上,因为它最符合我们的优先事项:低运营成本(计算和人力)、低认知开销、支持性社区以及透明的管理——同时满足我们的功能要求和预算。在 Linkerd 指导委员会工作了一段时间后(他们喜欢诚实的反馈和社区参与),我了解到它与我自己的工程原则有多么的契合。Linkerd 最近在 CNCF 达到毕业状态,这是一个漫长的过程,强调了该项目的成熟及其广泛采用。

关于作者

img

Chris Campbell 担任软件工程师和架构师已有十多年,与多个团队和组织合作落地云原生技术和最佳实践。他在与业务领导者合作采用加速业务的软件交付策略和与工程团队合作交付可扩展的云基础架构之间分配时间。他对提高开发人员生产力和体验的技术最感兴趣。