一行代码:开启 eBPF,代替 iptables,加速 Istio
首页>>云原生>>正文


Merbridge 项目开源上线,只需要在 Istio 集群执行一条命令,即可直接使用 eBPF 代替 iptables,实现网络加速!






01

Merbridge 开源上线
网络加速再上一个台阶

以 Istio 为首的服务网格技术,正在被越来越多的企业所瞩目。Istio 使用 Sidecar 借助 iptables 技术实现流量拦截,可以处理所有应用的出入口流量,以实现流量治理、观测、加密等能力。

然而,使用 iptables 的技术,需要对出入口都拦截,会让原本只需在内核态处理两次的链路,变成四次,造成大量的性能损失,这对一些性能要求高的场景有明显的影响。

但是正如 “一切问题都是时间问题” 所说,随着时间推移,新技术不断兴起,解决方案也随之而来。

近两年,由于 eBPF 技术的兴起,不少围绕 eBPF 的项目应运而成。eBPF 在可观测性和网络包的处理方面也出现了不少优秀的案例,如 Cilium、px.dev 等项目。「DaoCloud 道客」作为第一家正式获准加入 eBPF 基金会的中国公司,非常重视操作系统底层技术 eBPF 带来的革命性改变,深度参与 eBPF 的技术发展与研究应用,重新定义操作系统的底层逻辑。

在研究和应用 eBPF 技术过程中,「DaoCloud 道客」云原生技术工程师发现借助 eBPF 的 sockops 和 redir 能力,可以高效地处理数据包,通过结合实际生产场景,实现了用 eBPF 代替 iptables 为 Istio 进行加速,Merbridge 项目由此诞生。

现在,我们开源了 Merbridge 项目,只需要在 Istio 集群执行以下一条命令,即可直接使用 eBPF 代替 iptables 实现网络加速!

kubectl apply -f https://raw.githubusercontent.com/merbridge/merbridge/main/deploy/all-in-one.yaml

注意:当前仅支持在 5.7 版本及以上的内核下运行,请事先升级您的内核版本。

利用 eBPF 的 sockops 进行性能优化

网络连接本质上是 socket 之间的通讯,eBPF 提供了一个 bpf_msg_redirect_hash (https://man7.org/linux/man-pages/man7/bpf-helpers.7.html)函数,用来将应用发出的包直接转发到对端的 socket,可以极大地加速包在内核中的处理流程。

这里 sock_map 是记录 socket 规则的关键部分,即根据当前的数据包信息,从 sock_map 中挑选一个存在的 socket 连接来转发请求。所以需要先在 sockops 的 hook 处或者其它地方,将 socket 信息保存到 sock_map,并提供一个规则 (一般为四元组) 根据 key 查找到 socket。

02

Merbridge 
的实现原理

下文将按照实际的场景,逐步介绍 Merbridge 详细的设计和实现原理,这将让您对 Merbridge 和 eBPF 有一个初步的了解。

Istio 基于 iptables 的原理

如图所示,当外部流量访问应用的端口时,会在 iptables 中被 PREROUTING 拦截,最后转发到 Sidecar 容器的 15006 端口,然后交给 Envoy 来进行处理 (图中 1-2-3-4 的红色路径)。

Envoy 根据从控制平面下发的规则进行处理,处理完成后,会发送请求给实际的容器端口。

当应用想要访问其它服务时,会在 iptables 中被 OUTPUT 拦截,然后转发给 Sidecar 容器的 15001 端口由 Envoy 监听 (图中 9-10-11-12 的红色路径),与入口流量的处理差不多。

由此可以看到,原本流量可以直接到应用端口,但是通过 iptables 转发到 Sidecar,然后又让 Sidecar 发送给应用,这种方式无疑增加了开销。虽然 iptables 在很多情况下是通用的,但是它的通用性决定了它的性能并不总是很理想,因此它不可避免地会在不同的过滤规则下,给整个链路增加延迟

如果使用 sockops 将 Sidecar 直接连接到应用的 Socket,就可以使流量不经过 iptables,加速处理流程,明显提高性能。

出口流量处理

如上所述,我们希望使用 eBPF 的 sockops 来绕过 iptables 以加速网络请求,同时希望能够完全适配社区版 Istio,所以需要先模拟 iptables 所做的操作。

iptables 本身使用 DNAT 功能做流量转发,想要用 eBPF 模拟 iptables 的能力,就需要使用 eBPF 实现类似 iptables DNAT 的能力。

这里主要有两个要点:

1. 修改连接发起时的目的地址,让流量能够发送到新的接口;

2. 让 Envoy 能识别原始的目的地址,以能够识别流量。

对于第一点,可以使用 eBPF 的 connect 程序修改 user_ip 和 user_port 实现。

对于第二点,需要用到 ORIGINAL_DST 的概念,这在 Linux 内核中是 netfilter 模块专属的。

其原理为:应用程序 (包括 Envoy) 在收到连接之后调用 get_sockopts 函数,获取 ORIGINAL_DST。如果经过了 iptables 的 DNAT,那么 iptables 就会给当前的 socket 设置 ORIGINAL_DST 这个值,并把原有的 IP + 端口写入这个值,应用程序就可以根据连接拿到原有的目的地址。

那么我们就需要通过 eBPF 的 get_sockopt 函数来修改这个调用 (不用 bpf_setsockopt 的原因是目前这个参数并不支持 SO_ORIGINAL_DST 的 optname)。

如上图所示,在应用向外发起请求时,会经过如下阶段: 

1. 在应用向外发起连接时,connect 程序会将目标地址修改为 127.x.y.z:15001,并用 cookie_original_dst 保存原始目的地址。

2. 在 sockops 程序中,将当前 sock 和四元组保存在 sock_pair_map 中。同时,将四元组信息和对应的原始目的地址写入 pair_original_dst 中 (之所以不用 cookie,是因为 get_sockopt 函数无法获取当前 cookie)。

3. Envoy 收到连接之后会调用 getsockopt 获取当前连接的目的地址,get_sockopt 函数会根据四元组信息从 pair_original_dst 取出原始目的地址并返回,由此完全建立连接。

4. 在发送数据阶段,redir 程序会根据四元组信息,从 sock_pair_map 中读取 sock,然后通过 bpf_msg_redirect_hash 进行直接转发,加速请求。

其中,之所以在 connect 时,修改目的地址为 127.x.y.z 而不是 127.0.0.1,是因为在不同的 Pod 中,可能产生冲突的四元组,使用此方式即可巧妙地避开冲突 (每个 Pod 间的目的 IP 不同,不会出现冲突的情况)

入口流量处理

入口流量处理基本和出口流量类似,唯一的区别是需要将目的地址端口改成 15006。 

但是需要注意,由于 eBPF 不像 iptables 能在指定命名空间生效,它是全局的,这就造成如果针对一个本来不是 Istio 管理的 Pod 或者一个外部的 IP 地址,也进行了修改端口的操作,那就会引起严重问题,会让请求无法建立连接。

所以这里设计了一个小的控制平面 (以 DaemonSet 方式部署) Watch 所有的 Pod,类似于 kubelet 那样获取当前节点的 Pod 列表,将已经注入 Sidecar 的 Pod IP 地址写入 local_pod_ips 这个 map。

当我们在做入口流量处理时,如果目的地址不在这个列表之中,就不做处理,让它走原来的逻辑,这样就可以比较灵活且简单地处理入口流量。 

其他流程和出口流量流程一样。

同节点加速

通过入口流量处理,理论上可以直接加速同节点的 Envoy 到 Envoy 速度。但这个场景存在一个问题,Envoy 访问当前 Pod 的应用时会出错。 

在 Istio 中,Envoy 访问应用的方式是使用当前 PodIP 加服务端口。经过上述入口流量处理后,我们会发现由于 PodIP 也存在于 local_pod_ips 中,那么这个请求会被转发到 PodIP + 15006 端口,这显然是不行的,会造成无限递归。

这样我们就无法在 eBPF 中获取当前 ns 的 IP 地址信息,怎么办?

为此,我们设计了一套反馈机制:

即在 Envoy 尝试建立连接时,还是会走重定向到 15006 端口,但是在 sockops 阶段会判断源 IP 和目的地址 IP 是否一致。如果一致,代表发送了错误的请求,那么我们会在 sockops 丢弃这个连接,并将当前的 ProcessID 和 IP 地址信息写入 process_ip 这个 map,让 eBPF 支持进程与 IP 的对应关系。

当下次发送请求时,直接从 process_ip 表检查目的地址是否与当前 IP 地址一致。

Envoy 会在请求失败时重试,且这个错误只会发生一次,后续的连接会非常快。

连接关系 

在没有使用 Merbridge (eBPF) 优化之前,Pod 到 Pod 间的访问如下图所示:

在使用 Merbridge (eBPF) 优化之后,出入口流量会直接跳过很多内核模块,明显提高性能

同时如果两个 Pod 在同一台机器上,那么 Pod 之间的通讯将更加高效:

如上所述,通过使用 eBPF 在主机上对相应的连接进行处理,可以大幅度地减少 Linux 内核处理流量的流程,提升服务之间的通讯质量。

03

Merbridge 
的加速效果

使用 eBPF 代替 iptables 之后整体延迟的情况 (越低越好):

使用 eBPF 代替 iptables 之后整体 QPS 的情况 (越高越好):

以上数据使用 wrk 测试得出。

04

Merbridge 项目
广邀各路豪杰

以上介绍的都是 Merbridge 项目的核心能力,其通过使用 eBPF 代替 iptables,可以在服务网格场景下,完全无感知地对流量通路进行加速。同时,不会对现有的 Istio 做任何修改,原有的逻辑依然畅通。这意味着,如果以后不再使用 eBPF,那么可以直接删除掉 DaemonSet,改为传统的 iptables 方式后,也不会出现任何问题。 

Merbridge 是一个完全独立的开源项目,目前还处于早期阶段。我们希望有更多的用户或开发者参与其中,优化各组件的技术能力,推动服务网格发展壮大。

项目地址:https://github.com/merbridge/merbridge

社区交流:https://join.slack.com/t/merbridge/shared_invite/zt-11uc3z0w7-DMyv42eQ6s5YUxO5mZ5hwQ

微信社群:

扫码添加微信

备注【Merbridge】,讨论群




 本文作者 


刘齐均

「DaoCloud 道客」资深工程师

Istio 社区成员,Kubernetes 的贡献者,CKA 认证






参考文档:

  • https://github.com/merbridge/merbridge

  • https://developpaper.com/kubecon-2021-|-using-ebpf-instead-of-iptables-to-optimize-the-performance-of-service-grid-data-plane/

  • https://developpaper.com/go.php?go=aHR0cHM6Ly9qaW1teXNvbmcuaW8vYmxvZy9zaWRlY2FyLWluamVjdGlvbi1pcHRhYmxlcy1hbmQtdHJhZmZpYy1yb3V0aW5n

  • https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/listener_filters/original_dst_filter

  • https://ebpf.io/

  • https://cilium.io/

  • https://man7.org/linux/man-pages/man7/bpf-helpers.7.html





DaoCloud 公司简介

「DaoCloud 道客」云原生领域的创新领导者,成立于 2014 年底,拥有自主知识产权的核心技术,致力于打造开放的云原生操作系统为企业数字化转型赋能。产品能力覆盖云原生应用的开发、交付、运维全生命周期,并提供公有云、私有云和混合云等多种交付方式。成立迄今,公司已在金融科技、先进制造、智能汽车、零售网点、城市大脑等多个领域深耕,标杆客户包括交通银行、浦发银行、上汽集团、东风汽车、海尔集团、屈臣氏、金拱门(麦当劳)等。目前,公司已完成了 D 轮超亿元融资,被誉为科技领域准独角兽企业。公司在北京、武汉、深圳、成都设立多家分公司及合资公司,总员工人数超过 350 人,是上海市高新技术企业、上海市“科技小巨人”企业和上海市“专精特新”企业,并入选了科创板培育企业名单。


网址:www.daocloud.io

邮件:info@daocloud.io

电话:400 002 6898



给TA打赏
共{{data.count}}人
人已打赏

相关文章

eBPF、sidecars 和服务网格的未来

eBPF、sidecars 和服务网格的未来

eBPF 最近很火热,因为可以为云原生世界提供很多东西。由于 Cilium 之类的项目,它一直是 Kubernetes 集群的 CNI 层的流行选择。Linkerd 等服务网格通常与 Cilium 等 CNI 层一起部署,将 Linkerd 强大的 L7 处理与 Cilium 超快的 L3/4 处理相结合。 但是,eBPF 的网络技术到底有多强大?例如,它能否让我们完全替换 Linkerd 的 sidecars 代理,而只在内核中做所有事情? 在本文中,我将尽我所能评估这种可能性——尤其是当它与对用户的影响有关时。

Kalix:构建无服务器的云原生业务关键型应用程序,无需数据库

Kalix:构建无服务器的云原生业务关键型应用程序,无需数据库

Akka 背后的公司Lightbend最近推出了 Kalix,这是一种新的平台即服务产品,用于使用任何没有数据库的编程语言构建云原生、业务关键型应用程序。Kalix 是一个统一的应用层,它将编写软件所需的部分汇集在一起,并抽象出它们的实现细节。Lighbend 旨在为开发人员提供“创新的 NoOps 开发人员体验”。 Lightbend 的创始人兼首席执行官Jonas Bonér解释了 Kalix 的动机: 云生态系统的复杂性正在减缓工程和开发团队的速度。Kubernetes在管理、编排和确保容器的可用性和可扩展性

英特尔进军比特币挖矿设备市场

英特尔进军比特币挖矿设备市场

本文由半导体产业纵横综合   英特尔总部位于加利福尼亚州圣克拉拉   英特尔公司的新比特币挖矿芯片可能会成为多年来主导市场的中国挖矿设备制造商的第一个主要挑战者。   这家总部位于加利福尼亚州圣克拉拉的芯片制造巨头本月早些时候公布了其加密挖矿计划,并于1月份推出了第一代Bonanza Mine芯片。Jack Dorsey 的数字支付公司Block Inc.以及两家矿业公司Griid Infrastructure 和Argo Blockchain将在今年晚些时候收到第一批芯片。 &nbs

浅谈铁电存储器:如何实现下一代内存计算?

浅谈铁电存储器:如何实现下一代内存计算?

本文由半导体产业纵横编译自technews 因应人工智能、物联网、5G、车载等新兴科技所迎来的巨量资讯分析需求,近年来各国政府及国际知名大厂皆积极地投注大量资源,加速开发兼具提升运算速度以及降低耗能的下世代存储器。而新兴存储器技术选项中,当属铁电存储器最被看好,其原理、技术挑战与未来机会为何?(本文出自中国台湾清华大学工程与系统科学系巫勇贤教授,于闳康科技“科技新航道合作专栏”介绍《铁电存储器的原理、挑战与展望》文稿,经科技新报修编为上下两篇,此篇为上篇。)    Memory-Centric
云原生后端开发

Open Service Mesh(OSM)宣布v1.0.0

2022-2-14 15:48:25

企业存储后端开发

2022年最值得关注的10家半导体公司

2022-2-19 15:00:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索