服务网格中 sidecar 流量治理与多协议嗅探
服务网格架构已经是一个老生常谈的问题,服务的进出口流量经过 iptables 等技术手段被劫持到 sidecar,经由 sidecar 观察、治理之后再被转发到实际目标服务或者实例。
那么,在 sidecar 内部流量是如何处理并正确应用治理规则和转发的呢?
更具体一点,某个服务访问其他服务时,流量被劫持到到 sidecar 之后:
如何确认流量原始目标地址并实现正确转发?
如何确认哪些治理规则需要对当前流量生效?
接下来,本文将以 envoy sidecar 实现为例一点点说明 sidecar 是如何解决以上两个问题的(服务入口流量劫持和处理相对简单,所以本文主要关注出口流量处理)。
01
只是代理
说一千,道一万,envoy sidecar 也只是最简单不过的代理而已,它所有能做的事情都不会超过代理的范畴。
回顾代理的通用工作机制:接受下游连接和请求,按需对请求解析,然后经过一系列的模块或过滤器处理之后,将请求转发给上游服务。
在 envoy sidecar 中,接受下游的连接和请求的模块被抽象为 listener,而上游服务则被抽象为 cluster,形成如下结构:
当然,envoy 支持多 listener 机制,即同时监听复数个地址,并且可以通过 xDS 协议实现 listener 的动态更新。并且,envoy 允许 listener 并不实际绑定地址和端口,即不产生实际的地址监听。这两个特性对于 sidecar 来说很关键,不过并不复杂。
在对 sidecar 本身最简单的结构有了基本的了解之后,接下里就可以正式开始回答之前的问题了。
02
你去哪儿?
第一个问题,流量劫持之后,如何确认原始的目标地址并转发?
一般来说,sidecar 会创建两个特殊的 listener 并打开端口监听。一个作为服务入口流量劫持的入口(virtual inbound),一个作为服务出口流量劫持的入口(virtual outbound)。服务进出口流量被劫持后被分别发送 sidecar 这两个特殊 listener 处理。
以出口流量的 virtual outbound 为例。数据流量经过 iptables 劫持和重定向之后和 virtual outbound 建立连接。而 virtual outbound 则可以使用系统调用通过 SO_ORIGINAL_DST 获得该连接原始目标地址(IP 地址和端口)。该原始目标地址就可以用于辅助后续流量的转发。
当然,对于部分的应用层协议来说,其协议消息本身就可能会携带目标服务的相关信息。sidecar 也可以在对流量内容解析之后,根据其中的信息识别目标服务并转发。
举个例子,HTTP 协议。当客户端使用域名访问目标服务时,该域名就会直接被添加到请求的 host 当中。
根据配置,sidecar 也可以使用请求消息中的 host 将 HTTP 请求转发给目标服务。根据应用层消息中服务标识选择目标服务转发也是一个关键特性,在后续内容中还会提到。
03
路在何方?
在服务网格中,sidecar 的职责当然不只是简单的流量转发了,更重要的是流量观察及流量治理。所以,获取到了流量原始目标 IP 和端口之后,直接转发出去显然不是网格想要的,必须进行更进一步的治理。
这就是第二个问题了,如何使治理规则生效,又有哪些治理规则需要对当前流量生效呢?
答案其实就在第 1 小节中。作为代理的 sidecar 本身就具备流量观察、流量治理、负载均衡等基础能力,流量自 listener 进入,经过过滤器处理,最终通过 cluster 转发给目标服务。
同时,envoy sidecar 又具备灵活的多 listener 机制,且允许 listener 不产生实际监听。
那么,sidecar 完全可以为每一个服务创建一个不会实际监听地址的内部 listener(简称为 fake listener),以服务 VIP(注意,是服务 VIP,一个服务可能有很多个实例,每个实例都有实例 IP,但是一个服务一般只有一个 VIP)为索引。而所有与该服务相关的治理规则,都以各种过滤器配置下发到该 fake listener 当中。不同 fake listener 可以使用不同过滤器配置。
如上图所示,上层服务抽象中的服务以及治理规则最终被映射为 sidecar 中具体的 listener 和过滤器。
一般来说,在 K8S 的服务模型当中,客户端服务会使用目标服务域名访问目标服务。目标服务域名经 DNS 解析为目标服务 VIP。访问流量经 iptables 劫持,自 virtual outbound 进入 sidecar,在使用 SO_ORIGINAL_DST 获得流量原始目标地址(也即目标服务 VIP 地址和端口)之后,搜索该原始目标地址对应的 fake listener,然后把连接整个交给该 fake listener 处理,该 fake listener 会负责应用对应服务的治理规则(以过滤器实现)并将流量最终转发给目标服务(以 cluster 实现)。
04
公共的路
前文说过,sidecar 为每个服务都创建一个对应的 listener,以服务 VIP 为索引。可是如果存在大量的服务,那么就会创建大量的 listener,带来更大的资源开销。
另外,并不是所有服务模型中都有 VIP。比如在 Dubbo 的微服务模型中,就没有 VIP 的位置,所以就必须为每个实例创建一个 listener 保证流量被正确的治理和转发。且相同服务的所有实例对应的多个 listener 会应用相同的治理规则。
如此,显然会带来配置和资源的膨胀,给控制面和数据面都带来压力。
为了缓解该问题,envoy sidecar 提供了通配的 fake listener。通配 fake listener 使用 0.0.0.0:<port> (IPv4)为索引。
当以流量原始目标地址无法搜索到对应 fake listener 之后,就会根据流量原始目标端口搜索对应的通配 fake listener 来处理该流量。举例来说,如果一个请求(连接 or 流量)原始目标地址为 1.2.3.4:80,但是 sidecar 中不存在 1.2.3.4:80 fake listener 时,该请求就会被交由 0.0.0.0:80 通配 fake listener 处理。多个不同的 Dubbo 服务实例,也可以只创建一个对应的 fake listener。
但是,显然,通配 fake listener 会引入一些新问题。
首先,多个不同服务的流量最终会被同一个 fake listener 处理,为了保证服务治理规则能够正确、准确的生效,该通配 listener 内部必须要根据请求消息内服务标识(如 HTTP 中 host 请求头,如 Dubbo 请求中 interface)识别流量的目标服务并应用治理规则。
其次,通配 fake listener 可能会带来协议冲突问题。一般来说,同一地址(相同 IP,相同端口)只会使用一种协议(一般如此,当然也存在特殊情况,暂不讨论)。
可是,现在多个不同目标目标流量都可能聚集到同一 fake listener,必然存需要在同一 fake listener 处理多种不同协议流量的场景。比如说,目标地址 1.2.3.4:8080 提供 Dubbo 服务,目标地址 2.3.4.5:8080 提供 HTTP 服务,指向两者的流量最终都被 0.0.0.0:8080 处理。为了解决该问题,envoy sidecar 提供了协议嗅探机制,在同一 listener 中处理不同协议流量。
05
选择车道
如前文所述,请求流量和连接最终会交由 listener 处理,并以各种过滤器来实现各种治理规则,并且由于通配 fake listener,会大量出现需要在同一 listener 中处理不同协议流量的能力。
不同协议,可能有完全不同的消息格式和模型,显然需要不同的过滤器来进行处理。在 envoy sidecar 中就有相关的机制来支持该场景。
在 sidecar 的 listener 中,可以同时配置多组不同的过滤器,每组过滤器称为一个 filter chain。并且还提供了名为 listener filter 的特殊过滤器,可以对流量和连接进行预处理,并根据预处理的结果选择不同的 filter chain。
再次以 Dubbo 和 HTTP 协议为例。
当一个新的连接在 fake listener 中建立时,会首先经过 listener filter 预处理。它们会预读该连接上少量字节,如果其中包含 Dubbo Magic Number 和消息类型等字节,则为 Dubbo 协议;如果包含 HTTP 协议行,则为 HTTP 协议。最终 sidecar 会根据协议的不同选择不同的 filter chain 来处理,实现协议嗅探的效果。
利用好协议嗅探,就可以充分利用通配 listener 的能力,避免出现协议冲突。同时,对于同一地址(相同服务 IP,相同端口)不同协议的情况,也可以很好的处理。
本文以尽可能浅显的概念来说明服务网格中流量治理的实现原理与多协议嗅探机制要解决的问题。希望能够让读者对于服务网格流量治理和协议嗅探能有一个基本认知。更多相关内容可以阅读《深入理解 Isito:云原生服务网格进阶实战》一书。
京东满 100 减 50,扫码即购!
内容简介
Istio 在 1.5 版本后有了重大的架构变化,同时引入或改进了多项功能,例如,引入了智能 DNS 代理、新的资源对象,改进了对虚拟机的支持等。
本书以 Istio 新版本为基础编写而成,在持续追踪 Istio 社区最新动向的基础上,力求为读者提供最新、最全面的内容。
本书共 10 章,分别从概念、实践和生态扩展 3 个层面为读者系统介绍了 Istio 的知识。
本书特色
特色 1:云原生社区是我国服务网格技术推广的先驱阵地。本书由云原生社区多位技术专家合力撰写完成,内容专业,质量保障。
特色 2:本书经多次修订,基于 Isito 较新的版本和特性进行讲解。
特色 3:本书图文并茂,示例丰富,包含进阶,既能夯实基础,又能突破瓶颈。
大咖赞誉
Service Mesh 已深入人心,近些年演化出的 Database Mesh、Event Mesh、IO Mesh、Chaos Mesh 等都在快速发展,这些充满活力的理念和项目一定会掀起一股新的 Mesh 浪潮。
——张亮 SphereEx 创始人、Apache ShardingSphere VP
云原生社区组织了一批贡献者对 Istio 做了深入解读和实践分享,能让技术团队少走弯路、少踩坑,真正领悟服务网格的价值。
——刘超 腾讯云 T4 架构师
假以时日,相信 Istio 必将大放异彩。当此时刻,这本《深入理解 Istio:云原生服务网格进阶实战》足以满足我们对服务网格的所有期待。
——费良宏 Amazon Web Service 首席架构师
本书汇集了云原生社区多名工程师的实践经验,由浅入深,全面介绍了 Istio 的功能、原理及高阶实战经验,是一本难得的从入门到进阶技术书。
——徐中虎 Istio 社区 Steering Committee,华为云原生开源团队核心成员
本书详细介绍了 Istio 新架构中的各个组件、功能及相关生态。相信大家可以从中学习到成熟的 Service Mesh 技术和架构设计思想。
——吴晟 Tetrate 创始工程师、Apache SkyWalking 创始人、Apache 软件基金会首位中国董事
知识汇聚成书,经验落于文字,Istio 庞大的体系架构和纷繁复杂的特性得以被清晰地呈现。相信这本书可以帮助读者了解 Istio,掌握 Istio。
——敖小剑 ervice Mesh 布道师
面向读者
评论