作者 | 刘勤龙、 张晓龙在基础设施领域,从谈云计算到聊云原生,无论技术怎么革新,作为业务流量入口四层负载均衡都在默默的支撑着业务的运行,随着业务规模扩大,其中稳定、高性能是业务对四层负载均衡的核心诉求,买硬件四层负载均衡太贵,纯软件实现规模又上不去成本还高,唯有基于开源方案自研才能破局。高性能负载均衡不好做,本文分享一些实践经验,主要讨论“网易数帆的高性能负载均衡是如何基于开源负载均衡软件 DPVS 打造的”。1 为什么选择 DPVS
目前高性能负载均衡研发的一个流行方案是使用 DPDK(Data Plane Development Kit),这是一个用于包数据处理加速的软件库,使用了网卡用户态驱动、零拷贝、内存 Hugepage 和 Polling 模式等技术。业界基于 DPDK 开发负载均衡主要有两种模式,一是直接在 DPDK 库上自研或者移植负载均衡业务逻辑代码,二是使用 DPDK 作为加速通道加速已有的负载均衡的开源软件。
DPVS 就是一个使用 DPDK 软件库加速 LVS(DPDK+LVS)的高性能负载均衡开源软件。
https://github.com/iqiyi/dpvs
网易数帆选择基于 DPVS 开发新一代四层负载均衡,是因为 DPVS 既解决了 LVS 的性能瓶颈问题,又具备 LVS 的丰富的负载均衡业务逻辑,这使得团队可以把主要精力放在四层负载均衡和云内网络框架适配、运维监控、稳定性和软硬结合提升性能的优化上,而非重复开发负载均衡业务逻辑。
本文从 DPVS 云化场景改造、资源隔离保障系统稳定性、软硬件结合提高系统性能和监控运维功能增强四个方面分享网易数帆高性能四层负载均衡实践之路。
2 云化场景的改造
云化场景的核心改造涉及到如下三个方面内容:
云化网络架构适配
用户源地址透传设计
健康检查框架设计
这三个方面的改造目标是让网易数帆四层负载均衡具备“连通虚拟网络且隔离租户”、“透传真实的源 IP 地址给业务“、“集中管理健康检查流量”的能力。这些能力是网易数帆四层负载均衡产品化开发的基础功能要求,满足这些要求的四层负载均衡才可以支撑起云场景(容器云 / 虚拟机云 / 裸金属云等)的业务,下文逐一介绍实现要点。
云化网络架构适配
图 1.
如图 1 所示,云化场景的网易数帆四层负载均衡工作在中间层,负载均衡上联通过 ISP(互联网服务提供商)网络连接用户;下联通过 VxLAN 网络对接云化网络。负载均衡集群 HA 采用多活方式,负载均衡集群成员通过 BGP 协议发布负载均衡的 VIP 地址路由形成等价路由,集群内所有负载均衡服务器成员业务配置均相同,可相互替代。
图 2.
如图 2 所示,网易数帆四层负载均衡外网配置使用 KNI(Kernel NIC Interface)口 bond2.kni 和 DPDK Bond 口 bond2;发布路由的程序 Quagga,Quagga 通信网络依赖于 Linux 内核协议栈,而外网的网卡被 DPVS 用户态程序接管,因此 Quagga 需要将借助 bond2.kni(DPDK 创建的虚拟内核口)口将 BGP 通信流量发给外网路由设备, 而 bond2 口则负责业务流量的收发。
网易数帆四层负载均衡内网配置使用 bond1 口,并根据组网需求建立对应的 VLAN 子接口负责和云网络宿主机网络连通,和 VPC 通信数据需要使用开发的 VXLAN 模块进行 VXLAN 封装和解封装。
增加 VxLAN 处理模块
VxLAN 模块主要是用来连接云网络和隔离租户的,其属于云化网络连通性中非常关键的部分,所有发给云网络的数据包需要先进行 VxLAN 封装, VxLAN 模块就必须足够的简单和高性能,还要方便控制面程序进行管理配置。
VxLAN 模块在开发之初参考了下面两种方案:
选择 1: 参照 Kernel VxLAN 机制
选择 2: 参照 Openv Switch VxLAN
但是网易数帆最后选择了第 3 种,去除 VxLAN 口的逻辑概念,将 VxLAN 封装和解封装直接使用数据面实现,选择该方法的考虑是以下三点:
性能更优,直接进行 VxLAN 数据包的封装和解封装,在选择后端时候,VxLAN 封装信息就已经具备,这个时候少了一个选择 VxLAN 口的过程;
实现简单,直接流程中实现 VxLAN 封装和解封装就不需要进行 VxLAN 口管理;
逻辑清晰,控制面就不需要关注 VxLAN 口建立和删除。
实现方法命令举例,使用如下方法建立云化场景的后端:
ipvsadm -A -t 60.191.87.35:2022 -s wrr ipvsadm -a -t 60.191.87.35:2022 -r 192.168.1.178:8700 -T 10.182.6.87-10.182.4.59-5015 -m -w 100
建立监听 60.191.87.35:2022,后端地址是 192.168.1.178:8700,vxlan 封装信息是源 IP 地址是 10.182.6.87,目的 IP 是 10.182.4.59 和租户 VNI 5015。
用户源地址透传设计
用户地址透传是指负载均衡后端程序能够获取到客户端的公网地址,该功能是云上用户的强需求,用户获取到源地址后可以进行地域用户画像、黑白名单和地域用户行为分析等。设计支持云化网络场景时候就必须解决用户地址透传问题。
网易数帆的分析是:流量在经过中间层的四层负载均衡,如果四层负载均衡采用 FNAT 模式,会导致地址源地址丢失(因为 FNAT 会更换源地址为 LOCAL 地址),无法满足用户地址透传的需求,因此我们决定使用 DNAT 模式,这里重点描述下遇到的问题以及解决方法。
遇到的问题是:
社区 DPVS DNAT 模式只支持单 CPU Core。
社区主推使用 FNAT,DNAT 单 CPU Core 模式使用的人比较少,存在不稳定因素。
社区无法实现 DNAT 模式多 CPU Core,这是社区的一大缺点,其无法使用多 Core 和硬件网卡类型以及架构关联很大。社区实现精妙点是会话(类似于 conntrack)无锁,每 CPU 会话独立管理,为了达到此要求,需要正反向流量使用一个 CPU 处理,因为社区支持的是经典网络的场景,在多业务 CPU CORE DNAT 模式下,从后端回来数据包(反向流量)无法找到固定的特征使用硬件分流一定回到正向流量所在的 CPU。
图 3.
因此云化场景需要解决 VPC 云主机后端回包的问题,网易数帆采用了新型网卡支持的 rte_flow 支持的使用 VxLAN inner dst mac 进行反向流量的硬件分流解决了此问题,具体解决过程描述如图 4 所示:
图 4.
四层负载均衡采用双臂部署,通过双网卡实现,每个 CPU 固定绑定一个队列,外网网卡的 rss 硬件功能根据数据包的五元组把数据包 Hash 到外网网卡硬件队列里,绑定该队列 CPU 会使用该 CPU 预先关联的 MAC 地址作为 Vxlan inner src MAC 将流量发给云网络;后端记录该 mac 并作为发包 Vxlan inner dst MAC 发出;内网网卡根据 VxLAN 数据包内层的目的 MAC 地址进行精确匹配把从后端来的数据包放到与内层 MAC 绑定的 rx 队列中,因为 rx 队列和 CPU 一一绑定,所以从后端回来的数据包能回到正向流量处理的 CPU。
详细过程举例如下:
数据流量发给四层负载均衡外网口时候 rss 到了外网口 q3 队列,在 CPU3 上建立正向会话;
CPU3 进行 VxLAN 封装将 VxLAN 内层头的 src MAC 更换成 02:02:00:00:00:03 发给云化网络,这个 src MAC 地址 03 代表 CPU Core ID。
宿主机所在的 SDN 程序会记录该发包五元组对应的源 MAC,后端发给负载均衡流量时候会查询该记录,将 VxLAN inner dst MAC 换成 02:02:00:00:00:03;
四层负载均衡的内网网卡根据 VxLAN inner dst MAC 进行数据分流,根据网卡硬件 rte_flow 配置的策略,将反向流量发给内网口的 q3,从而 CPU3 继续处理。
设计新的健康检查框架
健康检查是四层负载均衡重要的组成部分,其帮助负载均衡判断业务后端服务是否处于正常工作状态,并且及时剔除不可工作的后端服务,始终让负载均衡的后端服务处于健康状态,确保过负载均衡的业务稳定运行。
云化场景下的后端处于云化网络中,传统的健康检查程序是 socket 程序实现的,socket 不支持 VxLAN 封装,无法连通云网络的后端,因此传统的健康检查程序在云化场景中无法正常工作。为了解决传统健康检查面临的问题,网易数帆提供了健康检查通道技术,帮助健康检查程序连通云网络,传统的健康检查程序零改动的即可检查云化网络的业务后端服务。
图 5.
那么使用 Kernel 协议栈的健康检查程序和位于用户态协议栈的健康检查通道是如何协同工作的呢?如图 5 所示:
健康检查程序不需要改动,直接将想要检测的后端云主机地址和端口改成健康检查通道的预先分配的地址和端口;
建立程序和通道接口地址端口的的绑定关系,建立通道和后端地址端口的绑定关系(间接建立可健康检查程序和后端地址待和端口的绑定关系);
健康检查流量被预先配置的路由和预先配置的静态 ARP 信息牵引到 bond2.kni 口,然后这个流量进入到健康检查通道;
检查通道将流量进行 FNAT 转换和进行 VxLAN 封装后发给对应的后端;
从 VPC 后端返回的流量反向运行上述逻辑,控制流量通过 bond2.kni 口发给传统健康检查程序。
这样设计的健康检查机制有如下优点:
健康检查程序透明,健康检查通道是工作在数据面的逻辑层概念,可以理解其为中间代理层,健康检查通道全权代理健康检查程序的检查行为,对健康检查程序透明,传统网络的健康检查程序可直接被使用对云化网络后端进行检查行为;
运维方便,健康检查通道统一管理了所有租户的健康检查行为;
简单,这样的架构,使健康检查通道解耦了健康检查和云化网络连通的逻辑,并且提供接口供控制面使用配置上也非常简单;
通用,这样的结构也适用于经典网络场景。
3 资源隔离保障系统稳定性
DPVS 原生框架已经将负载均衡数据处理会话做到 CPU 级别隔离,该机制很大的提升了会话的并发和新建能力,此外原生框架采用了 DPDK 作为底层加速通道,已经提供了基础的高性能框架,但是从实际运行业务的稳定性角度去考虑,其框架上仍有很大的改进点,下面先分析原生框架存在的问题,再给出网易数帆的解决方案。
图 6.
如图 6 所示,将 DPVS 框架按照流量源的差异性分为六个部分;图中使用 6 个序号表示:
健康检查前半部分流量
健康检查后半部分流量
BGP 心跳和配置同步前半部分流量
BGP 心跳和配置同步后半部分流量
控制面配置流量
负载均衡转发业务流量
问题 1: 控制面对接模块和 KNI 模块会相互影响
1 和 3 需要 master cpu0 运行 KNI 模块处理逻辑,将流量从和内核的共享队列中取出;5 也需要 master cpu0 处理用户业务配置,而用户业务配置量级存在突发和不确定性,会独占 master cpu0,导致序号 1 和 3 流量处理不及时而被丢弃。简要描述该问题是,控制面对接模块和 KNI 模块因争抢 master cpu0 计算资源而互相影响。
问题 2:BGP 通信流量和业务流量相互影响
4 属于 BGP 通信流量的后半部分,该流量社区原生处理是轮询使用各个 slave CPU 将数据包放到绑定的队列中发到外网,BGP 通信流量依赖外网网卡收发队列资源和所有 slave CPU 计算资源;6 属于负载均衡业务流量,业务流量具备非常明显的突发性,当发生流量突发时候,会导致外网网卡的队列资源和 CPU 资源被长时间占用,BGP 通信流量因获取不到队列和 CPU 资源,数据包被丢弃,BGP 产生断连。
问题 3:健康检查通道的流量和业务流量相互影响
2 会用 slave CPU1 和下联口队列 1 将数据包收发给 VPC 后端;6 的业务流量具备明显的突发性,正像在问题 2 中解释的那样,也会使健康检查通道被影响,可能导致健康检查工作异常,进而引发业务无法提供服务。
经过分析,上述三个问题描述了各个流量之间的相互影响和资源依赖,社区原生框架工作在业务流量相对稳定、配置流变动小、普通规模的后端和稳定的组网环境还可以,但是为达到我们产品化级别的稳定性要求,我们还需要做大量工作,所以我们需要使用资源隔离机制保障系统稳定性,网易数帆的解决方法如图 7:
图 7.
控制面对接模块独占 CPU n+1,KNI 模块使用 master cpu0 处理,两个模块 CPU 级别物理独立,解决问题 1;
BGP 通信的流量使用 CPU n 和 qn,业务流量使用 CPU1… CPU n-1 和 q1…qn-1, 两个模块 CPU 和外网队列物理级别独立,解决问题 2;
健康检查通道使用 CPU n、下联口的 qn 队列,业务使用上下联口的 CPU1…CPUn-1、q1…qn-1 ,健康检查通道的流量和业务流量物理资源隔离而不相互影响,解决问题 3;
我们采用的这样的解决方法,解决了提出的原生框架的三个缺陷,但是也引入了新的问题,由图 7 可知,BGP 通信的流量和健康检查通道的流量会共用 CPU n, 共用就会产生影响,但是经过实际极限性能测试,BGP 通信的流量和健康检查通道的流量都不大,一个物理 CPU n 处理完全足够,所以在实际业务中不用担心这个问题。
4 软硬件结合提高系统性能
高性能低成本,一直是数据面开发者追求的目标,我们在启动新负载均衡项目时候,定下的目标是千万级别的并发、千万级别的 PPS、百万级别的新建能力。因为这个级别的性能指标可以帮助公司满足业务需求;DPVS 是 DPDK 和 LVS 的结合体,具备 DPDK 的性能优势(Kernel by-pass 、RX Steering and CPU affinity、Zero Copy、Polling instead of interruptd 等), 继承这些优势,可以帮助实现千万级别的过包率。我们从使用软硬结合机制提高业务最关注的并发能力和业务秒杀场景所需要的新建能力。
会话无锁的实现
会话无锁是并发和新建能力所需要的核心技术。这块我们创新的新开发了 DNAT 模式,使用网卡硬件分流(例如:rss 和 rte_flow)和后端 SDN 软件的设计可以把一个会话的正反向流量都在一个 CPU core 处理,这样分在不同 CPU core 上的会话互不影响,会话之间也就不需要加锁了。上文中 Dnat 模式实现已经讲述了这一点。
使用网卡硬件卸载特性
除了使用上面介绍的网卡的硬件分流 rss 和 rte_flow 外,还使用网卡卸载了 VxLAN 数据包的内层 L4 的 Checksum 计算,我们下一步计划使用 Mellanox 25G CX5 网卡的 VxLAN 和 Qos 硬件卸载功能进一步提升新建能力和 PPS 能力。
5 监控运维功能增强
监控运维能力是负载均衡组件的硬实力的代表,我们基于网易内部业务实践运维需求,这块做了大量的工作,下面简要描述下,后续会出文专门对监控运维进行讨论。
多维度的监控能力
业务维度:新增 VIP 级别统计,精确到负载均衡的后端级别,额外开发 VIP 维度的各个连接数统计、VIP Qos 丢包统计、后端级别的连接数统计等 ;
CPU 维度:精确到 CPU 级别,CPU 维度的业务计数(并发连接数、丢包、等);
系统维度:查看 CPU 使用率,丢包率统计,定位丢包发生位置点确认是否是 DVPS 导致业务问题等手段 ;
有了上述多维度的监控,通过业务资源维度的参考,当业务产生异常时候,能够清楚反映到监控的指标中,且经过业务和资源维度的对比,可以确定问题发生的模块,以及该问题发生在哪个数据面 CPU 是否和网卡有关系等。
日志分级管理
日志手段是组件的基础能力,在日志能力上,我们进行了分模块和日志分级别方式来提升日志记录的灵活性;不同的场景和模块可进行日志开启动作,并且指定特定模块的日志级别。
问题排查手段
关于运维手段,我们开发了条件计数功能。条件计数是一种出现连通性问题时候的一种辅助定位手段。为了更精准的定位和跟踪流量的功能,为了简化条件的复杂性和性能做平衡,目前仅仅提供源地址维度的条件;我们想通过该手段做如下跟踪:
跟踪是否收到其配置的源地址的发出的 ARP request 和 ARP reply;
跟踪是否收到其配置的源地址发出的 ICMP 数据包;
跟踪是否收到其配置的源地址发出的数据包;
跟踪某一个配置的源地址触发的流量是否到负载均衡流程,从负载均衡流程是否发出,该地址触发流量从后端回来时候是否进入负载均衡流程,是否从负载均衡流程发出。
6 总结
目前,网易数帆以 DPVS 为框架完成的新一代高性能的负载均衡已经稳定运行一年多,支撑网易内部网易传媒、网易云音乐、网易严选等各大业务方,各项性能指标都符合预期,其中新建连接能力达到百万级别,并发连接能力千万级别满足了业务需求,这是网易数帆拥抱开源,结合现有云计算架构和业务落地的一次有意义的实践,此外我们在功能和监控运维痛点解决上也做了大量设计工作,这个后续再讨论。
作者简介
刘勤龙,网易杭州研究院资深云计算开发工程师,7 年服务端开发和优化经验,负责网易数帆四层负载均衡数据面设计,参与网易轻舟服务网格性能优化,目前专注于轻舟云原生 Serverless 平台底层的开发和优化工作。主要关注 Kubernetes、Istio、Knative、Cilium 等技术领域。
张晓龙,网易技术委员会委员,网易数帆轻舟业务部技术总监,2012 年浙江大学博士毕业后加入网易杭州研究院,负责基础设施研发 / 运维至今。在虚拟化、网络、容器、大规模基础设施管理以及分布式系统等技术架构有多年经验,当前主要兴趣点在云原生技术方向。
今日推荐文章25岁网安CEO被判刑12年,技术隔离后,顶尖***被out了?