编译 | Ethan
策划 | 云昭
Sidecar 的概念在容器和微服务的世界中变得如此普遍,以至于很容易将 Sidecar 视为云原生技术栈中自然、健康的一部分。
但如果你退后一步想一想,Sidecar 其实并不一定那么优雅,当微服务规模变得开始臃肿,Sidecar 模式也需要出现革新。
就如同现在的摩托车很少再有边车一样。毕竟,之所以被称为边车,是指如果你需要携带不适合它本身能承载的东西,你可以将其放在摩托车的边车上。然而,边车解决了摩托车容量有限的问题,但同时也大大减慢了行驶速度,并且使操纵变得更加困难。
服务网格的 Sidecar 模式
服务网格是技术堆栈中的一个层,有助于连接、保护和监控分布式应用程序的各个组件。通常单体应用程序,不会使用服务网格,因为它作为单个进程运行,没有复杂的依赖关系网络和进程间通信。但是,当将单体应用迁移到微服务架构时,就会遇到三大难题:一、必须应对各个离散的微服务之间的相互通信的挑战;二、需要确保微服务事务是安全的;三、需要一种有效的方法来从每个微服务中收集可观察性数据。管理微服务的成本巨大,如果直接在微服务本身的代码中检测和处理这些问题,开发者将花费大量时间在每个微服务中繁琐地编写和维护自定义代码,以处理连接性、安全性和可观测性。
服务网格通过提供集中管理服务的方式解决了这个问题。从本质上讲,服务网格允许开发人员将管理微服务连接性、安全性和可观测性所需的大部分工作,“外包”给专用的基础设施层,而不必在微服务本身内处理这些任务。通过这种方式,服务网格有助于简化和标准化微服务的管理方式。当然,服务网格不能直接与微服务对话或集成,这时候“边车模式”出现了。Sidecar 成为了服务网格与微服务对话的方式。
在 Sidecar 模式下,需要在托管每个微服务的业务逻辑的主应用程序容器之外,部署一个特殊的 Sidecar 容器。Sidecar 托管一个服务网格代理,该代理负责管理微服务。如果在同一个 Pod 中运行 Sidecar 容器和主容器,则二者可以强制执行在服务网格中定义的治理规则。Sidecar 模式对于管理分布式应用程序中的微服务很有意义,这些应用程序部署为容器并使用 Kubernetes 进行编排。在没有更好的技术将服务网格连接到单个应用程序容器的情况下,将 Sidecar 容器与实际的微服务一起部署,是一种将服务网格编排到微服务架构中的简单直接的方法。
Istio 火起来是有原因的
今天有许多服务网格,比如 Linkerd 和 Traefik。但可能最流行的解决方案是 Istio,这是一种专为以 Kubernetes 为中心的堆栈而设计的开源服务网格。
来源:istio.io
Istio 通过提供两个主要组件来实现服务网格:1、一个数据平面,它依赖于运行 Envoy 代理的 Sidecar 容器来与各个微服务交互。2、控制平面,作为集中式进程运行,以提供服务发现、强制配置和安全流量。
Istio 的开源性质和对 Kubernetes 友好的设计使该工具成为迄今为止成千上万的云原生托管堆栈的核心部分。
依赖 Sidecar 的问题
Istio 和其他依赖 Sidecar 模式的服务网格的确解决了不少实际问题,但同时也埋下了许多问题的种子。Sidecar 并不是一个完美的解决方案,面对大规模的连接、保护和观察分布式应用程序的管理需求,像 Istio 这样的服务网格存在两个关键问题:高资源消耗和低性能。
1.资源开销
在分布式托管环境中,每个微服务旁边都需要运行一个 Sidecar 容器,会使运行中的容器总数增加一倍。这也就意味着应用程序最终会消耗更多的资源。
除了 Sidecar 容器本身消耗的资源外,编排器还也增加了管理 Sidecar 的负担。同时,开发者在部署和更新 Sidecar 时也会消耗更多的网络带宽。
这也就是说,当运行 Sidecar 时会占用相当一部分的资源,而留给实际应用程序可用的资源就会减少,这可能会在需求高峰期,带来较低的性能体验。当然,由于最终将需要更多节点(或具有更高资源分配的昂贵节点)来处理工作负载,托管成本也会随之攀升。
2.性能和延迟
除了托管 Sidecar 的成本之外,Sidecar 容器在网络流量流入和流出每个微服务时,都需要将自己介入其中,难免对性能造成拖累。在应用程序接收和响应请求之前,每个数据包都必须通过 Sidecar,这会增加延迟,并可能对用户体验产生负面影响。
边车模式下的 Istio 性能
Sidecar 容器的性能开销到底如何?让我们看一下 Istio 本身记录的相关数据。Istio 的数据显示每个 Envoy 代理每 1000 个请求将消耗 0.35 个 vCPU 和 40 MB 内存。当然,性能开销会根据配置 Istio 的确切用途而有所不同(使用的功能越多,开销就越高)。
因此,如果你有 10 个微服务,并且为每个微服务部署一个 Envoy Sidecar,则需要额外的 3.5 个 vCPU 和 400 MB 内存来托管它们。这可以很容易地转化为相当于额外的 VM 实例来运行 Sidecar。(根据 Istio 的说法,甚至还需要使用额外的 1 个 vCPU 和 1.5 GB 的控制平面。)另请注意,Istio 表示每个代理容器平均会在第 90 个百分位延迟上增加 2.65 毫秒。这就是说,当你使用 Sidecar 时,响应速度也将如数延迟。
2.65 毫秒看起来很短暂,但在一个每毫秒都很重要的网络世界中,它的破坏性也会极大,尤其是对于需要真正实时执行的应用程序。
基于 eBPF 实现“无边车”
开发人员和 IT 团队通常将 Sidecar 容器所产生的性能和延迟成本视为必要的弊端。使用带有 Sidecar 模式的服务网格比不使用服务网格要容易得多,并且必须在每个微服务中进行管理,因此他们很乐意为托管支付更多费用和/或接受性能损失,以便在其中集中微服务管理服务网格。
然而,今天,一个更美好的世界已经成为可能——多亏了 eBPF,它可以直接在 Linux 内核中运行超高效、超安全、动态代码,而无需处理内核模块或修改内核源代码。
对于需要服务网格的工程师来说,这意味着,使用 eBPF,传统上使用 Sidecar 容器实现的微服务治理可以通过 eBPF 程序在内核中处理。由于 eBPF 程序可以在 Kubernetes 集群中的每个(基于 Linux 的)节点上运行,它们可以直接在内核中管理微服务连接性、安全性和可观察性,而不必作为单独的 Sidecar 运行。这种方法与 Istio 等传统服务网格相比,非常有优势:
- 性能:由于 eBPF 程序消耗最少的资源,与使用 Sidecar 架构相比,它们将显着降低运行服务网格的开销。
- 简单性:基于 eBPF 的服务网格将消除部署和管理一套 Sidecar 容器的需要。
- 可见性和控制性:通过直接在内核中运行,eBPF 程序在可以从容器内访问哪些数据以及可以对它们施加哪些控制方面几乎具有无限的范围。在这方面,基于 eBPF 的网格将比那些依赖于边车容器的网格更强大。
利用 eBPF 来解决传统服务网格的缺点,是一个相对较新的想法。目前,开发人员越来越关注这一策略,Cilium 已经实施了这一策略。
Cilium:基于 eBPF 加速节点代理模式
eBPF 的美好未来
eBPF 作为服务网格解决方案的“潜力股”,正在成为开发人员在分布式应用程序中处理安全性、可观察性和管理方式的“明日之星”。它将开发者从 Sidecar 模型中解放出来,并允许将现有的代理技术集成到现有的内核命名空间概念中,提供了一种原生且高效的服务网格实现范式。
除了可以更轻松地收集丰富的数据以实现可观察性、并为在容器内和容器之间流动的数据提供必要的安全性之外,eBPF 也可以被用于服务网络的“内核级”创新,能够卸载越来越多当前由代理执行的功能,以一种更简单、更有效且资源消耗更少的方式,来管理微服务之间的交互。
Sidecar 会消失吗
不得不说,即便是一直采用“边车”的 Istio 也认识到了它的局限性。9 月 7 日,Istio 宣布了一种新的数据平面模式 Ambient Mesh,该模式的亮点是取消了以 Sidecar 为中心的架构,取而代之的是无 Sidecar 的方法,同时保留了 Istio 的零信任安全、遥测和流量管理的核心功能。
正如 Istio 官方所言:“自创立以来,Istio 架构的关键特征之一就是使用 Sidecar,但 Sidecar 模式并没有在应用程序和 Istio 数据平面之间提供完美的隔离,这导致侵入性较高、资源利用不足、流量中断等问题,用户需要有一个侵入性更低、更容易使用的选择。”当然,这并不是说 Istio 或者依赖“边车模式”的服务网格将退出舞台。我们可以想象这样一个世界:Istio 控制平面仍然存在,但数据平面由 eBPF 程序驱动,而不是在 Sidecar 容器中运行的 Envoy 代理。Istio 为服务发现和配置管理开发了许多强大的技术,这些功能都将在基于 eBPF 的服务网格中保有持久的魅力。可以预见,“边车模式”将在未来几年慢慢过时——就像连接在摩托车上的边车一样。那些优先考虑速度和效率的企业和开发者将再度拥抱 eBPF,挣脱 Sidecar 的限制。
参考链接
https://www.groundcover.com/blog/istio-service-mesh
https://isovalent.com/blog/post/2021-12-08-ebpf-servicemesh
https://istio.io/latest/blog/2022/introducing-ambient-mesh/