当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进? | U刻
技术分享/

当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

  • 当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    栏目:技术分享

    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同时访问。

    当P4遇见NAT64,UCloud如何快速从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防护。

    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    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以旁挂的形式存在。下面以云主机为例,通过业务流程来简要说明整个系统的工作机制:

    • 业务流程
    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    由于每个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与后端节点的比例进行了一系列测试与验证。

    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?
    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    上图分别对应于后端节点增加和减少的情况,通过上述测试可以发现,当Lookup表的size较小时,该算法的稳定性略差,以上述测试为例,当Lookup表的size为1024时,在扩容和缩容场景,会有将近百分之二的连接会受到影响(具体表现为entry改变),这点与论文Maglev论文中的结论基本一致。

    但是随着Lookup表的size增大,对已有连接的影响越来越小,最终逼近与1/n。具体到上述两图,当Lookup表的大小超过后端服务节点的2000倍时,连接中断的比例低于0.01%,但是由于没有connection track,整个NAT64 Access是无状态的,这就大大提升了NAT64 Access的稳定性,并且极大的减小了实现复杂度。

    NAT64 Access的工作原理

    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    NAT64 Access上承载着一张Lookup表,格式如下:

    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    需要说明的是,此处的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占用图。

    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    系统性能测试

    系统构建完成后,我们针对单台NAT64(NAT64服务器配置为CPU:32核;内存:64GB;网卡: X710 10Gb * 2)服务器进行了完整的性能测试,client是IPv6,server端是IPv4 双向udp数据流,一应一答。client发送请求到server,server端应答回到client。其中最为关键的CPS和并发连接数指标测试结果如下:

    • CPS测试结果:
    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?
    • 并发连接数测试结果:
    当P4遇见NAT64,UCloud如何快速从IPv4向IPv6演进?

    我们初始单set上线了16台NAT64服务器,因此单地域最高可实现3.2M CPS和1.6G的并发连接。此外,整个系统支持平滑的无缝扩容,支持任意添加NAT64 Access和NAT64服务器。

    当前,UCloud IPv6转换服务处于免费公测阶段,欢迎使用。