大家好,我是老马。
sofastack 其实出来很久了,第一次应该是在 2022 年左右开始关注,但是一直没有深入研究。
最近想学习一下 SOFA 对于生态的设计和思考。
SOFAStack-00-sofa 技术栈概览
MOSN(Modular Open Smart Network)-00-简单聊一聊
MOSN(Modular Open Smart Network)-01-是一款主要使用 Go 语言开发的云原生网络代理平台
MOSN(Modular Open Smart Network)-02-核心概念
MOSN(Modular Open Smart Network)-03-流量劫持
MOSN(Modular Open Smart Network)-04-TLS 安全链路
MOSN(Modular Open Smart Network)-05-MOSN 平滑升级原理解析
MOSN(Modular Open Smart Network)-06-MOSN 多协议机制解析
MOSN(Modular Open Smart Network)-07-Sidecar 模式
MOSN(Modular Open Smart Network)-08-MOSN 扩展机制解析
本文描述的是 MOSN 作为 Sidecar 使用时的流量劫持方案。
MOSN 作为 Sidecar 和业务容器部署在同一个 Pod 中时,需要使得业务应用的 Inbound 和 Outbound 服务请求都能够经过 Sidecar 处理。区别于 Istio 社区使用 iptables 做流量透明劫持,MOSN 目前使用的是流量接管方案,并在积极探索适用于大规模流量下的透明劫持方案。
区别于 Istio 社区的 iptables 流量劫持方案,MOSN 使用的流量接管的方案如下:
经过上述的服务发现过程,流量转发过程就显得非常自然了:
127.0.0.1:20882
,所以就会向这个地址发起服务调用1.2.3.4:20881
)127.0.0.1:20880
)上文通过在服务注册过程中把服务端地址替换成本机监听端口实现了轻量级的"流量劫持",在存在注册中心,且调用端和服务端同时使用特定SDK的场景中可以很好的工作,如果不满足这两个条件,则无法流量劫持。为了降低对于应用程序的要求,需要引入透明劫持。
iptables 通过 NAT 表的 redirect 动作执行流量重定向,通过 syn 包触发新建 nefilter 层的连接,后续报文到来时查找连接转换目的地址与端口。新建连接时同时会记录下原始目的地址,应用程序通过(SOL_IP
、SO_ORIGINAL_DST
)获取到真实的目的地址。
iptables 劫持原理如下图所示:
目前 Istio 使用 iptables 实现透明劫持,主要存在以下三个问题:
上述问题并非在所有场景中都存在,例如连接数不多且 NAT 表未被使用的情况下,iptables 是满足要求的简单方案。为了适配更广泛场景,透明劫持需要解决上述三个问题。
使用 tproxy 处理 inbound 流量
tproxy 可以用于 inbound 流量的重定向,且无需改变报文中的目的 IP/端口,不需要执行连接跟踪,避免了 conntrack 模块创建大量连接的问题。目前 Istio 支持通过 tproxy 处理 inbound 流量(需内核版本支持)。
使用 hook connect 处理 outbound 流量
outbound 方向通过 hook connect 实现透明劫持,原理如下:
无论采用哪种透明劫持方案,均需解决获取真实目的 IP/端口的问题:iptables 方案通过 getsockopt 获取,tproxy 直接读取目的地址,hook connect 方案读取方式与 tproxy 类似。
在内核版本 >=4.16 时,通过 sockmap 可缩短报文穿越路径,改善 outbound 方向的转发性能。
总结来看: