IstioCon 2022 全球线上会议,于北京时间 25 日晚上 11 点盛大开启,26 日早上 9 点,迎来中国场的开幕式。
「DaoCloud 道客」的服务网格技术专家、Istio 社区指导委员会成员刘齐均 (Kebe Liu),参与了 26 日的开源生态研讨会和主题演讲,为大家分享了「DaoCloud 道客」在 Istio 社区开源的项目 Merbridge。
在 Istio 社区中,一直都在讨论,使用 eBPF 替代 iptables 的可能性,但是至今还没有项目可以实现。开源项目 Merbridge 正是实现了这一点,仅用一行代码即可开启 eBPF 替代 iptables,实现 Istio 加速。
Merbridge 除了提供使用 eBPF 替代 iptables,还可以实现对 Istio 的无感加速,以及提供更多便捷的使用方式,提升 Linux 内核处理流量的效率和服务之间的通讯质量,满足高性能的需求。
Merbridge 具体是如何实现的呢?里面涉及很多复杂的处理环节,下面将介绍其中几个关键的点,为大家剖析其中的实现逻辑。
使用 eBPF 实现流量拦截
当应用与其他应用服务建立连接时,会经过如下步骤,在这一过程中,我们使用 eBPF 实现流量拦截。
首先,进行流量判断,识别从应用容器发送的流量 (由 UID 识别)是否是需要拦截的流量;如果是从 Sidecar 发出的流量,那么我们不应该对其做拦截,否则会导致无限重复定向到 Sidecar。
接着,修改连接发送的目的地址,从而让流量能够发送到新的接口,可以使用 eBPF 的 connect 程序修改 user_ip 和 user_port 实现:connect 程序会将目标地址修改为 127.x.y.z:15001,并用 cookie_original_dst 保存原始目的地址。
最后,Envoy (管理流量并控制流量如何发送) 收到连接请求消息后,为了让 Envoy 识别出原始的目的地址,以能够识别流量,可以通过 eBPF 的 get_sockopt 函数来修改这个调用,get_sockopt 函数会根据四元组信息从 pair_original_dst 取出原始目的地址并返回,由此建立应用之间的连接。
缩短路径,实现加速
网络连接本质上是 socket 之间的通讯,eBPF 提供了一个函数 [bpf_msg_redirect_hash],用来将应用发出的包直接转发到对端的 socket,可以极大地加速包在内核中的处理流程。
但是这会引发一个问题,sock_map 依赖的是一个 map,需要先在 sockops 的 hook 处或者其它地方,将 socket 信息保存到 sock_map,并提供一个规则 (一般为四元组) 根据 key 查找到 socket。
因为四元组在命名空间里面是隔离的,而 eBPF 是纯内核级别的,在不同的 Pod 中,可能会产生冲突的四元组,出现两个地址是相同的情况,该如何解决四元冲突呢?
四元冲突解决方案
为了解决四元冲突,sip、sport、dip 和 dport 中的任何变量都应该改变。
解决方案 1:将 dip 从 127.0.0.1 修改为 127.128.x.y,其中 x,y 在建立新连接时增加,以避免冲突。
解决方案 2:将 sip 从 127.0.0.1 修改为 Pod IP。
解决方案 3:引入 socket cookie 来识别每个连接
上述解决方案也存在一定的局限性。
对于解决方案 1,Merbridge 在早期阶段就采用了这种方法,但在 IPv6 网络中不起作用。
对于解决方案 2,eBPF 无法直接访问当前 pod 的 IP 地址信息。
对于解决方案 3,仅适用于高于 5.15 的高内核版本。
于是,Merbridge 找到了新的方案,修改原 IP。使用 CNI 插件的功能,在 Pod 创建时,将 Pod 的 IP 写入 map,这将监控 Pod 网络上的特定端口,并在 map 中将 socket 的标记设置为 Pod IP 的密钥。当 Merbridge 的 mb_connect 程序处理请求时,可以通过从当前网络中识别 socket 的标记,然后根据标记,从 map 中读取 IP ,来获取当前 IP 地址。
在 eBPF 里面想要去获取一个 Pod 的 IP ,逻辑上看似简单,但实际的实现过程是非常复杂的。目前此功能正在紧锣密鼓开发中,两周后将迭代到 Merbridge 的新版本中。
现场演示
为了让大家更直观地了解,Merbridge 的使用和一些性能表现,刘齐均 (Kebe Liu) 在分享中为大家做了一个 live demo。在 Istio 的正常运行时,直接装上 Merbridge 就可以实现无缝接入,兼容运行,无需对其他代码进行修改。
并对性能进行了简单测试,可以直观地看到Merbridge 的性能表现,对性能要求高的场景非常适用。后续,Merbridge 将提供更严谨和科学的性能测试报告。
工作规划
Merbridge 的下一步工作,将聚焦以下四个方面:
-
细化流量管理,使用 XDP 进行流量拦截
-
支持 IPv6
-
采用 Merbridge CNI 来兼容 Istio 的配置
-
实现交叉节点的加速
欢迎对 Merbridge 感兴趣的伙伴,加入 Merbridge 的开源贡献、技术讨论和使用。