【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

UCloud 基于 Linux 内核新特性的下一代外网网关设计及相关开源工作

  • 2019-11-11
  • 本文字数:4494 字

    阅读完需:约 15 分钟

UCloud基于Linux内核新特性的下一代外网网关设计及相关开源工作

UCloud 外网网关是为了承载外网 IP、负载均衡等产品的外网出入向流量,当前基于 Linux 内核的 OVS/GRE tunnel/netns/iptables 等实现,很好地支撑了现有业务。同时,我们也在不断跟踪开源社区的新技术发展,并将之用于下一代外网网关的设计。这些新特性可将系统性能和管理能力再提上一档,满足未来几年的需求。在方案设计研发过程中发现,新特性存在不少缺陷和 Bug,为此我们向开源社区回馈了 10 多个 patch,并融入到 kernel 5.0 版本中,帮助完善 kernel 功能并提升稳定性。


当前业界的多租户外网网关很多都是基于 OpenFlow 的 OpenvSwitch(OVS)方案,然而随着内核路由转发功能的不断完善,利用内核原生路由转发方式进行设计多租户外网网关系统成为一种可能。在这种方式下能有效的使用传统 iproute2 路由工具以及 iptables、nftables 等 Firewall 工具,并且随着 SwitchDev 技术的兴起,未来将网关系统迁移到 Linux Switch 上也成为一种可能。

现有 kernel 3.x 的不足

当前广泛使用的内核版本为 3.x 系列,例如 CentOS 7 全系列标准支持的内核为 3.10 版本,Fedora/Ubuntu 等 Linux 发行版也有大量使用。在 3.x 系列内核下存在着 IP tunnel 管理复杂、租户隔离性能损耗等问题。

1. IP tunnel 管理复杂

Linux 内核创建 IP tunnel 设备来建立点对点的隧道连接,创建时需指定 tunnel dst 和 tunnel key。因为宿主机之间两两建立连接,面向宿主机的目的地址众多,这样就会导致网关节点上需要创建成千上万的 tunnel 设备,在大规模业务环境下,tunnel 的管理将变得及其复杂。

2. 多租户隔离导致的性能下降

a. 公有云需要实现多租户隔离以确保用户间的安全和隐私。由于 VPC 网络下不同租户的内网地址可以重合,导致路由也有重合的可能性,此时需要通过大量的策略路由去隔离租户的路由规则,由于策略路由的链表属性,性能会随着链表长度的增加而急剧下降。


b. 由于 Firewall 和 NAT 的实现基于同样链式的 iptables,性能损耗同样可观。

3. netns 带来性能开销

通过 netns 实现租户路由和 Firewall 规则的隔离,但是 netns 会引入虚拟网卡和协议栈重入开销,使整体性能下降 20%左右。

三项内核新技术

为了解决原有方案存在的困扰,我们调研了大量行业主流方案和内核上游的新动向,发现 Lightweight tunneling(轻量级隧道,简称 lwtunnel)、Virtual Routing Forwarding(虚拟路由转发,简称 VRF)以及 nftable & netfilter flow offload(流卸载)三项内核新技术的特性,可以帮助规避原方案存在的缺陷。

1. Lightweight tunneling

Linux 内核在 4.3 版本中引入了轻量级隧道 Lightweight tunneling,它提供了通过 route 方式设置 tunnel 属性的方法,这样可以避免管理大量的 tunnel 设备。


创建隧道设备时指定 external 模式,利用路由设置的轻量级隧道通过 tun 设备发送报文。


2. Virtual Routing Forwarding

Linux 内核在 4.3 版本中引入了 VRF 的初步支持,并在 4.8 版本形成完备版本。Virtual Routing Forwarding 虚拟路由转发,可以将一台 Linux Box 的物理路由器当多台虚拟路由器使用,能很好的解决租户路由隔离问题,避免直接使用策略路由。因此,可以将不同租户的网卡加入租户所属的虚拟路由器中来实现多租户的虚拟路由。



3. flow offload

Nftables 是一种新的数据包分类框架,旨在替代现存的{ip,ip6,arp,eb}_tables。在 nftables 中,大部分工作是在用户态完成的,内核只知道一些基本指令(过滤是用伪状态机实现的)。nftables 的一个高级特性就是映射,可以使用不同类型的数据并映射它们。例如,我们可以映射 iif device 到专用的规则集合(之前创建的存储在一个链中)。由于是 hash 映射的方式,可以完美的避免链式规则跳转的性能开销。


Linux 内核在版本 4.16 引入了 flow offload 功能,它为 IP forward 提供了基于流的卸载功能。当一条新建连接完成首回合原方向和反方向的报文时,完成路由,Firewall 和 NAT 工作后,在处理反方向首报文的 forward hook,根据报文路由、NAT 等信息创建可卸载 flow 到接收网卡 ingress hook 上。后续的报文可以在接收 ingress hook 上直接转发,不需要再进入 IP stack 处理。此外,将来 flow offload 还将支持 hardware offload 模式,这将极大提高系统转发性能。



方案设计与优化实践

通过对上述三项新技术的研究,我们发现可以尝试设计一套基于路由的方式,实现多租户 overlay 网络的外网网关。在方案设计过程中,我们也碰到了诸如 lwtunnel 和 flow offload 功能不足,以及 VRF 和 flow offload 不能一起有效的工作等问题。最终我们都设法解决了,并针对这些内核的不足提交 patch 给 Linux 开源社区。

1. lwtunnel 发送报文 tunnel_key 丢失

问题描述:我们利用 lwtunnel 路由方式发送报文时,创建了一个 external 类型的 gretap tunnel,我们将命令设置了 id 为 1000,但是发送成功报文中没有 tunnel_key 字段。



问题定位:我们研究 iproute2 代码,发现由于 TUNNEL_KEY flag 并没有开放给用户态,所以 iproute2 工具并没有对 lwtunnel 路由设置 TUNNEL_KEY,导致报文不会创建 tunnel_key 字段。


提交 patch:我们给内核和用户态 iproute2 分别提交 patch 来解决这一问题:


iptunnel: make TUNNEL_FLAGS available in uapi


iproute: Set ip/ip6 lwtunnel flags


提交 patch 后,可以通过以下方式设置路由。


ip r r 2.2.2.11 via 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key
复制代码

2. lwtunnel 对指定 key 的 IP tunnel 无效

问题发现:为了能有效隔离租户路由,我们给每个租户创建一个基于 tunnel_key 的 gretap tunnel 设备。如下图,创建一个 tunnel_key 1000 的 gretap tunnel 设备,把 tunnel 设备加入租户所属 VRF,tunnel 设备能有效地接收报文,但并不能发送报文。



问题定位:研究内核发现,IP tunnel 在非 external 模式下即使指定了轻量级隧道路由,发送报文也没有使用它,导致报文路由错误被丢弃。


提交 patch:


ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel


提交 patch 后,在未指定 tunnel_dst 的非 external 模式 IP tunnel 下,能使用轻量级隧道路由进行发送报文。

3. external IP tunnel ARP 无法正常运行

问题描述:邻居 IP tunnel 进行了 ARP 请求,但是本端的 ARP 回应报文的隧道头中并没带 tunnel_key 字段。



问题定位:研究代码发现,tunnel 收到了对端的 ARP 请求,在发送报文 ARP 回复的时候会复制请求报文的 tunnel 信息,但是遗漏了所有 tun_flags。


提交 patch:


iptunnel: Set tun_flags in the iptunnel_metadata_reply from src

4. Flow offload 不能与 DNAT 有效工作

问题描述:Firewall 创建规则从 eth0 收到目的地址 2.2.2.11 的报文,DNAT 为 10.0.0.7, flow offload 无法工作。



问题定位:分析发现,客户端 1.1.1.7 —> 2.2.2.7 DNAT 到 server 10.0.0.7,第一个 reply 反向报文(syc+ack)使用了错的目的地址获取反向路由


daddr = ct->tuplehash[!dir].tuple.dst.u3.ip
复制代码


此时 dir 为反方向,所以 daddr 获取为原方向的目的地址,这个值是 2.2.2.7, 但是由于被 DNAT 过,真正的路由不应该通过 2.2.2.7 去获取,而是应该根据 10.0.0.7 这个值去获取


addr = ct->tuplehash[dir].tuple.src.u3.ip
复制代码


提交 patch:


netfilter: nft_flow_offload: Fix reverse route lookup

5. Flow offload 不能与 VRF 有效工作

问题描述:将网卡 eth0 和 eth1 加入 VFR 后,flow offload 不起作用。



问题定位:查看代码发现,原方向和反方向首报文进入协议堆栈后 skb->dev 会设置为 vrf device user1,创建 flow offload 规则的 iif 就是 user1。但是 offload 规则下发在 eth0 和 eth1 的 ingress hook 上,所以后续报文在 eth0 和 eth1 的 ingress hook 上不能匹配 flow 规则。


提交 patch:


netfilter: nft_flow_offload: fix interaction with vrf slave device


最终,我们根据两个方向查找路由的结果,设置 flow offload 规则的 iif 和 oif 信息来解决此问题。

6. VRF PREROUTING hook 重入问题

问题描述:配置网卡加入 VRF,firewall ingress 方向规则为接收目的地址 2.2.2.11 、TCP 目的端口 22 的报文,egress 方向规则为丢弃 TCP 目的端口 22 的报文。出现异常结果: 收到目的地址 2.2.2.11 TCP 22 目的端口的报文却被丢弃。



问题定位:研究发现网卡加入 VRF 后收到的报文会两次进入 PREROUTING hook,因为在进入 IP stack 时会进第一次 PREROUTING hook,然后被 VRF 设备接管后会再次进入 PREROUTING hook。上述规则第一次在 rule-1000-ingress chain 中 dst nat 为 10.0.0.7,第二次由于报文被 DNAT 后会错误的进入 rule-1000-egress,导致报文被丢弃。


提交 patch:我们给内核加了一个支持判断网卡类型的 match 项目,让用户态避免可知的第二次无效重入,内核态和用户态 nftables 分别提交了如下的 patch:


netfilter: nft_meta: Add NFT_META_I/OIFKIND meta type


meta: add iifkind and oifkind support


使用方法:


nft add rule firewall rules-all meta iifkind "vrf" counter accept
复制代码

原型验证

最终,我们成功地利用 lwtunnel、VRF 和 flow offload 实现多租户外网网关的原型验证。验证过程如下:

1. 首先创建原型环境。

a. netns cl 模拟外网 client, 地址为 1.1.1.7,tunnel src 172.168.0.7,配置发送路由;


b. netns ns1 模拟租户 1,内网地址为 10.0.0.7,外网地址为 2.2.2.11,tunnel src 172.168.0.11 tunnel_key 1000,配置发送路由;


c. netns ns2 模拟租户 2,内网地址为 10.0.0.7,外网地址为 2.2.2.12,tunnel src 172.168.0.12 tunnel_key 2000,配置发送路由;


d. Host 模拟外网网关,tunnel src 172.168.0.1,创建租户 VRF user1 和 use2,创建租户 IP tunnel tun1 和 tun2,配置转发路由。


原型环境图如下:



2. 创建 firewall 规则:

a. 租户 1 入向允许 TCP 目的端口 22 和 ICMP 访问,出向禁止访问外部 TCP 22 目的端口;


b. 租户 2 入向允许 TCP 端口 23 和 ICMP 访问,出向禁止访问外部 TCP 23 目的端口;


c. 在租户 tun1 和 tun2 设备上支持 flow offload。



最终,client 可以通过 2.2.2.11 成功访问 user1 tcp 22 端口服务,user1 不能访问 client tcp 22 端口服务;client 可以通过 2.2.2.12 成功访问 user2 tcp 23 端口服务,user1 不能访问 client tcp 23 端口服务。


待后续 hardware offload 功能完善以及网卡厂商支持后,我们会做进一步的开发验证。

写在最后

以上是本项目涉及的部分核心问题,这些 patch 特性都可以在 Linux kernel 5.0 版本里获取。我们把这期间为 Linux kernel 社区贡献的 patch 整理成了一份列表,希望能为开发者提供帮助,读者可以点击“阅读原文”阅览完整 patch list。


Linux 作为成熟的开源套件,一直是云厂商使用的主流操作系统,但在技术的更新迭代过程中,一些新特性在实际应用上也会存在稳定性、兼容性等方面的问题。我们在研究使用上游技术的同时,也一直积极探索、丰富开源技术功能,帮助提高开源技术稳定性。并将产出持续回馈给社区,与社区共同构建一个繁荣的开源生态。


本文转载自公众号 UCloud 技术(ID:ucloud_tech)。


原文链接:


https://mp.weixin.qq.com/s/I4GSv8TBm2jBxcEUUevhHQ


2019-11-11 13:52869

评论

发布
暂无评论
发现更多内容

微服务简介

insight

微服务 3月日更

滚雪球学 Python 之闭包操作,本系列第 8 篇文章

梦想橡皮擦

28天写作 3月日更

关于广东欢太科技可不可信?那是你还不了解

Geek_4a453c

企业 欢太 欢太科技

一步一步教你如何在Centos7中配置Kafka运行时环境

happlyfox

28天写作 3月日更

带你了解VXLAN网络中报文的转发机制

华为云开发者联盟

网络 网关 VXLAN 报文 分布式网关

“新作者 新入驻 新征程”第一季获奖名单

InfoQ写作社区官方

热门活动

2月大事件:度目CM-Mini智能面板机全新发布,飞桨PaddleGAN“复活”李焕英

百度大脑

百度 百度大脑

3月12日学习笔记

Nydia

翻译:《实用的Python编程》05_01_Dicts_revisited

codists

Python

ECMAScript 2016(ES7)新特性简介

程序那些事

JavaScript ecmascript ES6 程序那些事 es7

算法喜刷刷之验证二叉树的前序序列化

Kylin

算法 3月日更 刷题笔记

这是看脸的时代吗——晕轮效应

Justin

心理学 28天写作 游戏设计

真·“拜师学艺”?2021中科院开源之夏,开源大牛1V1&万元奖金只等你来!

京东科技开发者

开源 开源社区

物联网常用协议:MQTT、CoAP、LwM2M、HTTP、LoRaWAN和NB-IoT

不脱发的程序猿

物联网 通信协议 28天写作 3月日更 物联网常用协议

你以为在做的是微服务?不!你只是做了个比单体还糟糕的分布式单体!

程序猿DD

微服务

“种”下黑科技,守护每株绿,“植”了!

华为云开发者联盟

华为 AI IoT modelarts 森林

华云大咖说 | 华云数据与瀚高软件携手共建国产云生态 助力政企用户安全可靠发展

华云数据

力扣(LeetCode)刷题,简单题(第27期)

不脱发的程序猿

面试 LeetCode 28天写作 算法面经 3月日更

《未来世界的幸存者》读书笔记

SilentMacUser

极客时间 互联网 技术学习 阅读 阮一峰

一起来学习LiteOS中断模块的源代码

华为云开发者联盟

代码 华为云 LiteOS 中断 中断控制器

(28DW-S8-Day20) 以太坊账户

mtfelix

28天写作

如何成为一名架构师?

xcbeyond

程序人生 方法论 架构师 成长与思考 3月日更

聊聊什么是CommonJs和Es Module及它们的区别

蛙人

大前端 js ES6

细粒度授权在安全领域的重要性

龙归科技

安全 iam 细粒度 ABAC PBAC

区块链应用解决方案赋能到农产品溯源上究竟能解决什么问题?

源中瑞-龙先生

硬核!一文学完Flink流计算常用算子(Flink算子大全)

五分钟学大数据

大数据 flink 28天写作 3月日更

【LeetCode】验证二叉树的前序序列化Java题解

Albert

算法 LeetCode 28天写作 3月日更

对标阿里P9Java架构师面试题,已助我拿下字节、蚂蚁、滴滴三家Offer

Java架构追梦

Java 阿里巴巴 架构 面试 滴滴

Python With 关键字和语句

HoneyMoose

《精通比特币》学习笔记(第八章)

棉花糖

区块链 学习 3月日更

植树节,种个二叉树吧?

悟空聊架构

数据结构 算法 二叉树

UCloud基于Linux内核新特性的下一代外网网关设计及相关开源工作_服务革新_文旭_InfoQ精选文章