IPv4 发展到今天已存在着诸多缺陷,比如地址枯竭、安全和服务质量难以保证、路由膨胀等,这些问题将极大制约云计算等相关 IT 行业的发展。IPv6 以其更大的地址空间、更高的安全性等特点,能够很好的解决 IPv4 这些缺陷。
UCloud 于 2018 年上半年开始研发公网入口的 IPv6 转换,依托 NAT64 技术和可编程 P4 交换机,现已成功推出了免费的 UCloud 公网入口 IPv6 转换服务。该产品功能简洁易用,申请 EIP 后一键开启 IPv6 转换,无需任何改造,即可对外提供 IPv6 的访问。目前,UCloud IPv6 转换服务已成功用于云主机、EIP、负载均衡、容器集群、堡垒机等产品。地域内单集群(16 台 NAT64 服务器,4 台 P4 交换机)最高可实现 3.2M CPS 和 1.6G 的并发连接,且可在以后的演进过程中平滑扩容。
UCloud IPv6 演进战略步骤
对于 IPv6 技术的预研与探索,UCloud 早在几年之前就已经开始了,内部已有完整的 IPv6 预研方案。但我们仍需要清晰的认识到网络基础设施的改造不是一蹴而就的,这里面不仅涉及到技术难题的攻克,其本身还是个非常巨大的工程问题。
而且最重要的是在不影响用户现有业务的同时,让用户的业务慢慢的迁移至 IPv6。正是基于这种考虑,针对 IPv4 到 IPv6 的演进,UCloud 制定了以下战略:
1.2018 年完成互联网入口 IPv6 转换服务,使 UCloud 超过百分之五十的产品能够支持 IPv6,客户只需在 EIP 开启 IPv6 转换服务,无需更改任何业务即可使业务获得对外提供 IPv6 访问服务的能力,实现业务和 IPv6 网络的平滑对接;
2.2018 年完成管理网 IPv6 改造,使得依托于管理网的云产品诸如主机入侵检测,容器镜像库等产品支持 IPv6;
3.2019 年完成 UCloud 主要产品支持 IPv6,其中 VPC、ULB(UCloud 负载均衡)等重要产品将于 2019 Q2 之前支持 IPv6,具备主动访问 IPv6 网络能力;
4.2019 年完成 IDC 双栈改造,使得数据中心内部支持 IPv6,提供完整的 IPv6 支持。
IPv6 从技术到落地的过程中,UCloud 做了很多工作,也遇到了比较多的挑战。本文接下来将从技术的角度详细介绍 UCloud IPv6 转换服务的实现与优化演进。
UCloud IPv6 转换服务
◆ NAT64 及其技术挑战
在实现技术上,UCloud 使用有状态的 NAT64 技术来实现 IPv6 转换服务,NAT64 是一种通过网络地址转换(NAT)形式促成 IPv6 与 IPv4 主机间通信的 IPv6 转换机制。NAT64 网关需要至少一个 IPv4 地址和一个包含 32 位地址空间的 IPv6 网段来完成 IPv4 与 IPv6 协议间的翻译。
NAT64 将这个 32bit 的 IPv4 地址嵌入的 IPv6 目的地址转换成目的 IPv4 地址,源 IPv6 地址转换成一个特定的源 IPv4 地址。NAT64 网关则创建 IPv6 与 IPv4 地址间的映射,这可以为手动配置,也可以自动确定。
如下图所示,UCloud IPv6 转换功能基于 NAT64 实现,可为用户现有 IPv4 的 EIP 生成一个 IPv6 地址,在用户不修改现有 IPv4 网络和相应服务的情况下,相应云资源和服务可以获得被公网 IPv6 访问的能力,并可使得用户的云资源和服务被 IPv4 和 IPv6 同时访问。
IPv6 与 IPv4 之间的转换是一种有状态转换,考虑整个系统层面的稳定性与扩展性需求,IPv6 转换服务的实现主要有两大技术关键点:
高可用,由于 IPv6 转换服务是有状态服务,因此必须保证在集群内节点发生变化时,不能影响已有连接(准确的说影响不超过 1/n,其中 n 标识后端节点数目);
安全防护,由于 IPv6 转换服务是有状态服务,因此当碰到恶意攻击(比如 DDoS),很容易导致服务器被打挂进而导致服务不可用,因此一定的 DDoS 防护能力对整个系统来说至关重要。
◆ 系统架构
根据以上关键点,我们开始着手设计基于 NAT64 和 P4 交换机实现 IPv6 转换功能的系统架构,如下图所示,其中 NAT64 Access 使用 P4 交换机实现,通过 NAT64 Access 的一致性 Hash 实现高可用。同时在 NAT64 Access 对 CPS 进行限速,实现 DDoS 防护。
NAT64 Access 与物理交换机 1 组成三层网络,通过 BGP 向物理交换机 1 宣告一个/96 的 IPv6 地址段,作为该地域的 IPv6 prefix。POP1 与 POP2 中 Access 向外宣告的地址段相同,实现负荷分担和 POP 点级别的容灾。同理,POP 点内两个 Access 之间也是负荷分担和容灾。
Access 与物理交换机 2 以及 NAT64 服务器组成二层网络,NAT64 服务器北向通过 BGP 向 Access 宣告 VIP,Access 即可获得 VIP 对应的下一跳信息(MAC 地址)。当收到 Internet 流入的入向 IPv6 报文时,将所述报文的 MAC 地址设定为某个 NAT64 服务器的 MAC 地址,即可实现将报文送达至特定的 NAT64 服务器。同时 NAT64 服务器南向需要向物理交换机 4 宣告一个源地址池,实现回程的可达性。
需要说明的是,在实际部署中,物理交换机 2 和 1 通常合一部署,形成 NAT64 Access 以旁挂的形式存在。下面以云主机为例,通过业务流程来简要说明整个系统的工作机制:
业务流程
由于每个 NAT64 服务器上会配置一个源地址池且互不重叠(其中 IPv4_1 是 NAT64 源地址池中的一个地址,IPv4_2 对应 EIP)并且南向通告了该地址池,因此云主机的响应报文(目的地址为源地址池中的地址,即 IPv4_1)能够通过路由到达相应的 NAT64 服务器。
◆ 当 P4 遇见 NAT64
NAT64 Access 支持高可用
通过上文的系统架构,可以发现,通过物理交换机可以实现 POP 点级别的负荷分担和容灾,但是实际上系统能够实现高可用的关键在于当 NAT64 服务节点的状态发生变化(比如扩容或者某个节点 down)时,系统需要保证已有连接不被破坏,这就要求 NAT64 Access 选择后端节点时能够支持一致性 Hash,因此实质上 NAT64 Access 的最重要属性是一致性 Hash 网关。
在各大云计算厂商的实现中,一致性 Hash 网关的实现,DPDK 是当前主流的实现方案。但是 DPDK 也存在以下缺陷:
基于 DPDK 的应用可以达到很高的包转发速率,但这是通过多服务器、多核负载均衡实现的。且负载均衡算法通常是由硬件交换机或者网卡实现,并不能被软件定义。如果网络中出现单个大象流,无法被硬件交换机或者网卡的负载均衡算法很好的分发,就会造成单根网线或者单个 CPU Core 出现拥塞,对业务造成巨大影响。 随着网络带宽从 10G 向 25G、40G、50G、100G 的演进,DPDK 需要更强力的 CPU 才能够达到线速,而更强力的 CPU 通常价钱也很昂贵,不利成本。特别是单 Core 的主频越高,价格越贵,且主频增加之间和价格增加是非线性关系。 因此,我们最终决定采用 P4 可编程交换机(基于 Barefoot Tofino 芯片实现)来实现 NAT64 Access,实际上 UCloud 早在 2017 年就开始预研 P4 可编程交换机,并且目前已有基于 P4 可编程交换机的 GW 灰度上线。相比于 DPDK 网关,P4 可编程交换机具有诸多优势:
1.与 DPDK 相比,有更高的转发性能(1.8T~6.4T);
2.转发性能稳定,不受 CPU Loading 等影响;
3.单线 100G,可以避免单线拥塞;
4.P4 语言开放性好,可编程能力强;
5.很好的生态圈,支持 P4 Runtime。
Maglev Hash
Maglev 算法的选择及验证
在一致性 Hash 算法的选择时,我们选择了 Google Maglev 项目中使用的 Hash 算法(下文简称 Maglev Hash),该算法的核心优势在于当后端服务节点发生变化时,具有极致的稳定性。并且 Lookup 表的 size 保持不变,非常适合于 P4 交换机来承载 Lookup 表。(原始论文:Maglev: A Fast and Reliable Software Network Load Balancer)
根据该论文中对一致性 Hash 的介绍可以看出,Maglev Hash 算法本质上设计算法让每个后端按照一定的规则去填满数组 Lookup 表的 Empty Entry,确保所构造出来的 Lookup 表的元素中,所有后端服务器出现的次数尽可能相等(实质上,根据算法出现次数最多的节点和最少的节点之间的差值最大为 1),因此可以达到极致的平均性能。
Maglev Hash 算法所产生的 Lookup 表,虽然有着极致的平均性能,但是也有一个缺陷,那就是当后端服务节点发生变化时,会有部分连接中断的情况(理想的一致性 Hash 算法中断连接的比例为 1/N,Maglev Hash 可能存在略微超过 1/N)。
在 Maglev 项目中,通过 Connection Track 表来弥补这一缺陷,然而 Connection Track 将带来一系列缺点,使得 NAT64 Access 有状态,易于收到攻击。从论文中可以看出,当 Lookup 表的 size 大于后端节点的 100 倍时,连接中断的情况低于 2%。但是 2% 还是一个相对比较高的比例,本着严谨的态度,我们在扩容和缩容(缩容也对应某台 NAT64 服务器 Down 机)场景下又针对 Lookup 表 size 与后端节点的比例进行了一系列测试与验证。
上图分别对应于后端节点增加和减少的情况,通过上述测试可以发现,当 Lookup 表的 size 较小时,该算法的稳定性略差,以上述测试为例,当 Lookup 表的 size 为 1024 时,在扩容和缩容场景,会有将近百分之二的连接会受到影响(具体表现为 entry 改变),这点与论文 Maglev 论文中的结论基本一致。
但是随着 Lookup 表的 size 增大,对已有连接的影响越来越小,最终逼近与 1/n。具体到上述两图,当 Lookup 表的大小超过后端服务节点的 2000 倍时,连接中断的比例低于 0.01%,但是由于没有 connection track,整个 NAT64 Access 是无状态的,这就大大提升了 NAT64 Access 的稳定性,并且极大的减小了实现复杂度。
NAT64 Access 的工作原理
NAT64 Access 上承载着一张 Lookup 表,格式如下:
需要说明的是,此处的 Lookup 表实际上是由 Maglev 中数张 Lookup 表构成的,通过 vip 加以区分。
具体工作机制如下:
不同的 NAT64 集群通过 BGP 向 NAT64 Access 宣告不同的 VIP,NAT64 Manager 通过 GRPC 获取 NAT64 Access 的路由表信息和邻居表信息,获取各个 VIP 以及对应的下一跳 MAC 地址信息。然后遍历所有 VIP,根据每个 VIP 的下一跳信息调用 Maglev Hash Engine 生成相应的每个集群的 entry list(具体值为各个 NAT64 的 MAC 地址)。所有的 entry list 以及 VIP 构成上述 Lookup 表。
当数据面收到报文时,将根据 EIP 查询到 VIP(通过另外的表以及控制面相应逻辑实现,在此不再展开),然后根据数据包的源 IP、目的 IP、源端口、目的端口、调用 P4 语言的 Hash 函数通过计算得到 entry index,最后根据 VIP 和 entry index 匹配 Lookup 表,设置目的 MAC,至此就完成了后端服务节点的选择。
NAT64 Manager 将持续监控 NAT64 Access 的路由表以及邻居表,一旦某个 VIP 的下一跳发生了改变(比如扩容场景或者某个 NAT64 Down),将重新调用 Maglev Hash Engine 重新生成该 VIP 对应的 Lookup 表中对应的那部分 entry,并通过 GRPC 修改相应的 entry,实现节点变化时的快速响应。
NAT64 Access DDoS 安全防护
由于 IPv6 转换服务本身是有状态的,也就意味着有可能受到 DDoS 的攻击,因此我们在 NAT64 Access 上对每个 EIP 针对 TCP SYN 报文进行入向和出向 PPS 限速。因为 UCloud 在公网接入有着强大的安全保护和 DDoS 检测、清洗等,因此 NAT64 Access 上所执行的 SYN 报文的限速仅仅是作为一个补充和二次防护。但是其优点在于无需检测分析而直接进行限速,这可以使得在极端攻击场景下缩短 NAT64 服务的不可用时间(安全中心完整的 DDoS 防护通常都存在检测和分析等步骤,存在一定程度的滞后性)。
目前单个 EIP 的 SYN 报文的速率限制在 50000,超过 50000 时会进行丢包。该参数是可调的,如果用户业务层面有超大 CPS 的需求,UCloud 相关的技术支持人员也可以协助进行调整。
P4 表配置优化
Tofino 芯片包含 4 条 pipeline,每个 pipeline 包含 12 个 stage,目前主流的场景还是所有 pipeline 使用相同的表配置,即使用同一份 P4 代码。但是一旦两个表之间相互依赖,就没办法放入同一个 stage,这是底层芯片的执行逻辑决定的。
考虑业务逻辑的复杂性,数据面通常需要定义很多的表才可以完成整个业务逻辑,且这些表之间彼此依赖性很高。因此在实际编码过程中出现了 stage 用光,但是每个 stage 资源利用率很低,具体到我们的项目,资源利用率低就会导致一台 NAT64 Access 能够支持的 EIP 数量有限。这种问题通常有以下三种解决方案:
优化表配置,或者修改一定的业务逻辑,减少表之间的相互依赖,这样能够大大提高 stage 资源的利用率; 由于 ingress 和 egress 虽然共享 stage,但是 ingress 和 egress 的表之间从硬件层面没有任何依赖关系。因此将业务逻辑拆分,一部分放于 ingress,另一部分放于 egress。这种方案比较简单易行,且通常收效明显; Pipeline 串行,拆分业务逻辑,每个 pipeline 放置一部分业务逻辑,不同 pipeline 之间通过自定义 metadata 传递信息。这种方案也是一种行之有效的方案,且能够提升 Tofino 整体的表项空间,可以预见未来可能会有很多这样的应用。 在 NAT64 项目中,我们采用了 1 和 2 结合的方案,经过优化后,资源利用率达到百分之七十左右(没有优化之前只达到百分之三十左右)。下图是我们优化后 Tofino 芯片的资源利用图和 Table 占用图。
系统性能测试
系统构建完成后,我们针对单台 NAT64(NAT64 服务器配置为 CPU:32 核;内存:64GB;网卡:X710 10Gb * 2)服务器进行了完整的性能测试,client 是 IPv6,server 端是 IPv4 双向 udp 数据流,一应一答。client 发送请求到 server,server 端应答回到 client。其中最为关键的 CPS 和并发连接数指标测试结果如下:
CPS 测试结果:
并发连接数测试结果:
我们初始单 set 上线了 16 台 NAT64 服务器,因此单地域最高可实现 3.2M CPS 和 1.6G 的并发连接。此外,整个系统支持平滑的无缝扩容,支持任意添加 NAT64 Access 和 NAT64 服务器。
当前,UCloud IPv6 转换服务处于免费公测阶段,欢迎使用。