Servicemesh的问题
1 - (2021)在生产环境使用 Istio 前的若干考虑要素
内容出处
在生产环境使用 Istio 前的若干考虑要素
深度落地 Istio 两年的若干思考。
https://cloudnative.to/blog/the-facts-of-using-istio/
作者 陈鹏 发表于 2021年2月25日
前言
2021 年伊始,如果你想要在生产环境中落地 Service Mesh,那 Istio 一定已经在你的考虑范围之内。
Istio 作为目前最流行的 Service Mesh 技术之一,拥有活跃的社区和众多的落地案例。但如果你真的想在你的生产环境大规模落地 Isito,这看似壮观美好的冰山下,却是暗流涌动,潜藏着无数凶险。
本文是笔者深度参与百亿量级流量生产环境研发和落地 Istio 两年来的经验总结和一些思考,以期读者在自己生产环境引入 Isito 前,能有所参考和启发,做好更充足的准备,能更轻松的“入坑” Istio。
如果你对 Service Mesh 的概念还不甚了解,可先行阅读《云原生时代,你应该了解的 Service Mesh》。
使用 Isito 前的考虑要素
使用 Istio 无法做到完全对应用透明
服务通信和治理相关的功能迁移到 Sidecar 进程中后, 应用中的 SDK 通常需要作出一些对应的改变。
比如 SDK 需要关闭一些功能,例如重试。一个典型的场景是,SDK 重试 m 次,Sidecar 重试 n 次,这会导致 m * n 的重试风暴,从而引发风险。
此外,诸如 trace header 的透传,也需要 SDK 进行升级改造。如果你的 SDK 中还有其它特殊逻辑和功能,这些可能都需要小心处理才能和 Isito Sidecar 完美配合。
Istio 对非 Kubernetes 环境的支持有限
在业务迁移至 Istio 的同时,可能并没有同步迁移至 Kubernetes,而还运行在原有 PAAS 系统之上。 这会带来一系列挑战:
- 原有 PAAS 可能没有容器网络,Istio 的服务发现和流量劫持都可能要根据旧有基础设施进行适配才能正常工作
- 如果旧有的 PAAS 单个实例不能很好的管理多个容器(类比 Kubernetes 的 Pod 和 Container 概念),大量 Istio Sidecar 的部署和运维将是一个很大的挑战
- 缺少 Kubernetes webhook 机制,Sidecar 的注入也可能变得不那么透明,而需要耦合在业务的部署逻辑中
只有 HTTP 协议是一等公民
Istio 原生对 HTTP 协议提供了完善的全功能支持,但在真实的业务场景中,私有化协议却非常普遍,而 Istio 却并未提供原生支持。
这导致使用私有协议的一些服务可能只能被迫使用 TCP 协议来进行基本的请求路由,这会导致很多功能的缺失,这其中包括 Istio 非常强大的基于内容的消息路由,如基于 header、 path 等进行权重路由。
扩展 Istio 的成本并不低
虽然 Istio 的总体架构是基于高度可扩展而设计,但由于整个 Istio 系统较为复杂,如果你对 Istio 进行过真实的扩展,就会发现成本不低。
以扩展 Istio 支持某一种私有协议为例,首先你需要在 Istio 的 api 代码库中进行协议扩展,其次你需要修改 Istio 代码库来实现新的协议处理和下发,然后你还需要修改 xds 代码库的协议,最后你还要在 Envoy 中实现相应的 Filter 来完成协议的解析和路由等功能。
在这个过程中,你还可能面临上述数个复杂代码库的编译等工程挑战(如果你的研发环境不能很好的使用 Docker 或者无法访问部分国外网络的情况下)。
即使做完了所有的这些工作,你也可能面临这些工作无法合并回社区的情况,社区对私有协议的扩展支持度不高,这会导致你的代码和社区割裂,为后续的升级更新带来隐患。
Istio 在集群规模较大时的性能问题
Istio 默认的工作模式下,每个 Sidecar 都会收到全集群所有服务的信息。如果你部署过 Istio 官方的 Bookinfo 示例应用,并使用 Envoy 的 config dump 接口进行观察,你会发现,仅仅几个服务,Envoy 所收到的配置信息就有将近 20w 行。
可以想象,在稍大一些的集群规模,Envoy 的内存开销、Istio 的 CPU 开销、XDS 的下发时效性等问题,一定会变得尤为突出。
Istio 这么做一是考虑这样可以开箱即用,用户不用进行过多的配置,另外在一些场景,可能也无法梳理出准确的服务之间的调用关系,因此直接给每个 Sidecar 下发了全量的服务配置,即使这个 Sidecar 只会访问其中很小一部分服务。
当然这个问题也有解法,你可以通过 Sidecar CRD 来显示定义服务调用关系,使 Envoy 只得到他需要的服务信息,从而大幅降低 Envoy 的资源开销,但前提是在你的业务线中能梳理出这些调用关系。
XDS 分发没有分级发布机制
当你对一个服务的策略配置进行变更的时候,XDS 不具备分级发布的能力,所有访问这个服务的 Envoy 都会立即收到变更后的最新配置。这在一些对变更敏感的严苛生产环境,可能是有很高风险甚至不被允许的。
如果你的生产环境严格要求任何变更都必须有分级发布流程,那你可能需要考虑自己实现一套这样的机制。
Istio 组件故障时是否有退路?
以 Istio 为代表的 Sidecar 架构的特殊性在于,Sidecar 直接承接了业务流量,而不像一些其他的基础设施那样,只是整个系统的旁路组件(比如 Kubernetes)。
因此在 Isito 落地初期,你必须考虑,如果 Sidecar 进程挂掉,服务怎么办?是否有退路?是否能 fallback 到直连模式?
在 Istio 落地过程中,是否能无损 fallback,通常决定了核心业务能否接入 Service Mesh。
Isito 技术架构的成熟度还没有达到预期
虽然 Istio 1.0 版本已经发布了很久,但是如果你关注社区每个版本的迭代,就会发现,Istio 目前架构依然处于不太稳定的状态,尤其是 1.5 版本前后的几个大版本,先后经历了去除 Mixer 组件、合并为单体架构、仅支持高版本 Kubernetes 等等重大变动,这对于已经在生产环境中使用了 Istio 的用户非常不友好,因为升级会面临各种不兼容性问题。
好在社区也已经意识到这一问题,2021 年社区也成立了专门的小组,重点改善 Istio 的兼容性和用户体验。
Istio 缺乏成熟的产品生态
Istio 作为一套技术方案,却并不是一套产品方案。
如果你在生产环境中使用,你可能还需要解决可视化界面、权限和账号系统对接、结合公司已有技术组件和产品生态等问题,仅仅通过命令行来使用,可能并不能满足你的组织对权限、审计、易用性的要求。
而 Isito 自带的 Kiali 功能还十分简陋,远远没有达到能在生产环境使用的程度,因此你可能需要研发基于 Isito 的上层产品。
Istio 目前解决的问题域还很有限
Istio 目前主要解决的是分布式系统之间服务调用的问题,但还有一些分布式系统的复杂语义和功能并未纳入到 Istio 的 Sidecar 运行时之中,比如消息发布和订阅、状态管理、资源绑定等等。
云原生应用将会朝着多 Sidecar 运行时或将更多分布式能力纳入单 Sidecar 运行时的方向继续发展,以使服务本身变得更为轻量,让应用和基础架构彻底解耦。
如果你的生产环境中,业务系统对接了非常多和复杂的分布式系系统中间件,Istio 目前可能并不能完全解决你的应用的云原生化诉求。
写在最后
看到这里,你是否感到有些沮丧,而对 Isito 失去信心?
别担心,上面列举的这些问题,实际上并不影响 Isito 依然是目前最为流行和成功的 Service Mesh 技术选型之一。Istio 频繁的变动,一定程度上也说明它拥有一个活跃的社区,我们应当对一个新的事物报以信心,Isito 的社区也在不断听取来自终端用户的声音,朝着大家期待的方向演进。
同时,如果你的生产环境中的服务规模并不是很大,服务已经托管于 Kubernetes 之上,也只使用那些 Istio 原生提供的能力,那么 Istio 依然是一个值得尝试的开箱即用方案。
但如果你的生产环境比较复杂,技术债务较重,专有功能和策略需求较多,亦或者服务规模庞大,那么在开始使用 Istio 之前,你需要仔细权衡上述这些要素,以评估在你的系统之中引入 Istio 可能带来的复杂度和潜在成本。
2 - (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 提供的安全态势相当或更好的安全态势。
智能路由
智能路由是另一个特性,它使网格能够在发送请求时“做正确的事”。场景包括:
- 使用延迟加权算法优化流量
- 拓扑感知路由以提高性能并降低成本
- 根据请求成功的可能性使请求超时
- 与编排系统集成以进行 IP 解析,而不是依赖 DNS
- 传输升级,例如 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 测试,那么解决方案需要支持以下内容:
- 对部署和回滚的精细控制,因为它可能同时进行多个不同的“测试”
- 能够捕获系统知道的自定义指标并可以根据这些指标做出决策
- 根据请求的特征暴露对流量方向的控制,其中可能包括解析整个请求正文
这需要实现很多,没有哪个服务网格是开箱即用的。最终,我们的组织选择了网格之外的特征标记解决方案,其以最小的努力取得了巨大的成功。
我们在哪里结束
最终,我们面临的挑战并不是服务网格独有的。我们工作的组织有一系列限制条件,要求我们对解决的问题以及如何解决问题采取务实的态度。我们面临的问题包括:
- 一个拥有大量不同技能的开发人员的大型组织
- 云计算和 SaaS 能力普遍不成熟
- 为非云计算软件优化的流程
- 碎片化的软件工程方法和信念
- 有限的资源
- 激进的截止日期
简而言之,我们人少,问题多,需要快速输出价值。我们必须支持主要不是 Web 或云计算的开发者,我们需要扩大规模以支持有不同方法和流程的大型工程组织来做云计算。我们需要将大部分精力集中在解决成熟度曲线较低的基本问题上。
最后,当面对我们自己的服务网格决策时,我们决定建立在 Linkerd 服务网格上,因为它最符合我们的优先事项:低运营成本(计算和人力)、低认知开销、支持性社区以及透明的管理——同时满足我们的功能要求和预算。在 Linkerd 指导委员会工作了一段时间后(他们喜欢诚实的反馈和社区参与),我了解到它与我自己的工程原则有多么的契合。Linkerd 最近在 CNCF 达到毕业状态,这是一个漫长的过程,强调了该项目的成熟及其广泛采用。
关于作者
Chris Campbell 担任软件工程师和架构师已有十多年,与多个团队和组织合作落地云原生技术和最佳实践。他在与业务领导者合作采用加速业务的软件交付策略和与工程团队合作交付可扩展的云基础架构之间分配时间。他对提高开发人员生产力和体验的技术最感兴趣。