VPP 的 NAT 技术原理
在OpenStack Neutron中主要有三种网络设备,路由器(Router),负载均衡器(LB)以及VPN,其中Router作为基础网络设备起到连接子网到子网、内网到外网的作用。不同子网之间的访问完全是由路由功能实现的,而内外网之间访问使用的是SNAT和DNAT技术。
作为NFV的底层技术FD.io VPP已经包含了路由功能,因此要想以VNF的形式实现Neutron中的vRouter,就必须解决内外网之间访问的问题。其中内网访问外网是通过SANT技术,其数据流信息如下:
当内网用户发起外网访问时,其数据包携带out2in信息到达Router,Router只需根据SNAT策略为其生成in2out信息与out2in信息的对应关系并将其记录在session表中,并将数据包携带的out2in信息改成in2out信息发送出去即可。当外网服务器收到Router发送的数据包后生成应答,应答数据包携带in2out信息到达Router后,Router根据之前session表中的记录找到out2in信息与in2out信息对应关系,并将数据包携带的in2out信息改成out2in信息发送出去即可。
当外网用户发起内网访问时,其数据包携带in2out信息到达Router,Router只需根据DNAT策略为其生成in2out信息与out2in信息的对应关系并将其记录在session表中,并将数据包携带的in2out信息改成out2in信息发送出去即可。当内网服务器收到Router发送的数据包后生成应答,应答数据包携带out2in信息到达Router后,Router根据之前session表中的记录找到out2in信息与in2out信息对应关系,并将数据包携带的out2in信息改成in2out信息发送出去即可。
对于ICMP Request 和 Response消息来说由于其没有port信息,可以用ICMP数据包中的id信息充当port信息;而对于ICMP差错报文来说,例如ICMP不可到达报文,可以从ICMP的消息体中解析出相应的out2in或者in2out信息。
networking-vpp 项目
社区邮件列表在 10.6 介绍了新项目 networking-vpp https://github.com/openstack/networking-vpp。这个项目将实现一个基于 VPP 的 ML2 Driver,以期获得高性能的虚拟网络。目前 networking-vpp 已有 3000+ 行代码,提供了 devstack 的插件,有兴趣的开发者可以用 devstack 尝试下,核心代码目前并不多,主要依赖于 vpp_papi 这个 Python binding, vpp_papi 可以达到 1500 messages/s 左右的性能,目前还远落后于 C 的实现(450000,得益于 VPP 控制平面共享内存的设计)。
现在 networking-vpp 已经可以工作在 vlan/flat 网络下,并且与原生的 l3, DHCP, Metadata 集成。
得益于项目比较新,很多设计借鉴了了以往的 ML2 Driver 里被验证不可靠或容易出问题的地方——使用 etcd 而非 RabbitMQ 通信,通过 journal 记录操作保证一致性等等。
当然 networking-vpp 目前也有一些明显问题,比如不支持安全组、overlay 等等,有待开发者们贡献了。(作者:于杨,UnitedStack有云)