如何在服务网格中避免复杂性问题

服务网格是 Kubernetes 世界的一个热门话题,但许多潜在的采用者已经失望地离开了。服务网格的采用受到了难以承受的复杂性和看似无穷无尽的供应商解决方案的限制。在我了解了这个领域之后,我发现采用服务网格有着巨大的价值,但它必须以轻量级的方式进行,以避免不必要的复杂性。尽管人们普遍感到失望,但服务网格的未来依旧光明。

边用边学

我进入服务网格的世界,始于我在一家历史悠久的财富 500 强科技公司担任云架构师。当我们开始实现服务网格时,我身边有很多优秀的工程师,但他们大部分在云开发方面几乎没有经验。我们的组织诞生于云之前,而且充分认识云的价值需要时间。我们的传统业务线主要聚焦于技术栈的硬件元素上,云决策最初是由为交付硬件或为该硬件提供固件和驱动程序而开发的流程驱动的。

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

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

我们的服务网格实现

我第一次听说服务网格是在 2015 年,那时我正在修补服务发现工具并寻找与 Consul 集成的简便方法。我喜欢将应用程序的责任转移到“sidecar”容器中的想法,并找到了一些可以帮助实现这一点的工具。大约在这段时间,Docker 有一个名为“连接(linking)”的功能,可以将两个应用程序放在一个共享的网络中,以便他们可以通过 localhost 进行通信。这个功能提供了一种类似于我们现在在 Kubernetes pod 中的体验:两个服务,独立构建,可以在部署时组合起来,以实现一些额外的功能。

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

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

我们对服务网格的实现非常实用,并且与该技术的核心特性非常一致。然而,许多营销宣传集中在需求较少的边缘案例上,在评估服务网格是否适合您时,能够识别这些干扰因素非常重要。

核心功能

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

标准化监控

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

自动加密和身份验证

证书管理很难做到正确。如果一个组织还没有在这方面投资,他们应该用一个网格来为他们做这件事。证书管理需要维护复杂的基础设施代码,伴随巨大的安全隐患。相反,网格能够与编排系统集成,以了解在需要时可用于实施策略的工作负载的标识。这造就了一个真正强大的安全处理方式,与那些由功能强大的 CNI(如 Calico 或 Cilium)提供的处理方式相当,甚至更好。

智能路由

智能路由是另一项功能,使网格能够在发送请求时“做正确的事”。用例包括:

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

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

可靠的重试

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

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

网络扩展性

服务网格的最佳属性可能是其可扩展性。它提供了一个附加的适应性层,可以承担接下来的任何挑战。sidecar 代理的设计模式是另一个令人兴奋的强大功能,即使有时候它被过度销售和过度设计来做用户和技术还没有准备好的事情。当社区等待看哪个网格“获胜”时(这反应了之前过度炒作的编排战),我们将不可避免地看到未来会有更多专门构建的网格,并且可能会有更多的最终用户构建属于他们自己的控制面板和代理来满足他们的用例。

服务网格分散关注点的功能

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

相反,来自服务网格项目的大部分沟通都围绕着听起来功能强大或令人兴奋但最终会分散关注点的功能。这包括:

强大的(即,“复杂的”)控制面板

很好地运行复杂的软件是非常困难的。这就是为什么如此多的组织使用云(通过使用完全托管的服务)来减轻这一负担。那么,为什么服务网格项目会让我们负责运维如此复杂的系统呢?系统的复杂性不是一种资产,而是一种负债,然而大多数项目都在兜售它们的特性集和可配置性。

多集群支持

多集群是当前的热门话题。最终,大多数团队将运行多个 Kubernetes 集群。但是多集群的主要痛点是,Kubernets 管理的网络被削减了一半。服务网格有助于解决 Kubernetes 的扩展问题,但这最终无法实现任何新功能。是的,多集群支持是必要的,但它对服务网格的承诺被过度推销了。

Envoy

Envoy 是一个很好的工具,但它被视为某种标准呈现,这是有问题的。Envoy 是众多开箱即用的代理之一,你可以将其作为服务网格的基础。但是 Envoy 本身并没有什么特殊之处,能够使其成为正确的选择。采用 Envoy 为你的组织提出了一系列重要问题,包括:

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

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

WASM

我是 Web Assembly(WASM)的超级粉丝,已经成功用它在Blazor构建了前端应用程序。然而,WASM 作为一种自定义服务网格代理行为的工具,使您完全处于与现有软件生命周期完全不同的全新软件生命周期!如果您的组织还没有准备好构建、测试、部署、维护、监控、回滚和版本代码,(影响通过其系统运行的每个请求),那么你还没有准备好 WASM。

A/B 测试

A/B 测试实际上是一个应用程序级别的问题。在基础设施层提供语言来启用 A/B 测试是可以的,但是没有简单的方法可以完全自动化大多数组织所需的 A/B 测试级别。通常,应用程序需要定义唯一的指标,即定义测试的积极信号。如果一个组织想要在服务网格级别投资 A/B 测试,解决方案需要支持:

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

这需要实现很多东西,没有现成的服务网格可以做到这一点。最终,我们的组织选择了网格之外的特性标记解决方案,以最小的努力获得了极大的成功,实现了这一点。

我们的最终方案

最终,我们面临的挑战并不是服务网格所独有的。我们工作的组织有一套约束条件,要求我们对我们解决的问题以及如何解决这些问题保持务实态度。我们面临的问题包括:

  • 一个拥有许多不同技能的开发人员的大型组织
  • 通常不成熟的云和 SaaS 功能
  • 针对非云软件优化的流程
  • 零碎的软件工程方法和理念
  • 有限的资源
  • 激进的最后期限

总而言之,我们人少,问题多,需要快速展现价值。我们必须支持那些不是主要进行 Web 或云开发的开发人员,我们需要进行扩展来支持大型工程组织使用不同的方法和流程来进行云计算。我们需要将大部分精力集中在解决成熟度曲线较低的基本问题上。

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

作者介绍:

Chris Campbell 已经担任软件工程师和架构师十多年了,与多个团队和组织合作来采用云原生技术和最佳实践。他将自己的时间分为两部分:一是与业务领导者合作,采用软件交付策略,加速业务;二是与工程团队合作,交付可扩展的云基础设施。他最感兴趣的是提高开发人员生产力和经验的技术。

原文链接:

How Unnecessary Complexity Gave the Service Mesh a Bad Name

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/DON6eGZEialxp4iWS3KE
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券