YAOTU INSIGHTS

可编程网卡芯片落地云网络:从OVS硬件卸载到vDPA与RDMA加速实践

可编程网卡芯片落地云网络:从OVS硬件卸载到vDPA与RDMA加速实践
这次想聊的是我们团队过去一年多里做的一件既头疼又过瘾的事把可编程网卡芯片真正落到云网络的日常运营中。起因并不复杂某大型云平台上的宿主机虚拟网络一直在吃 CPU 资源带宽从 25G 往 100G、200G 爬的时候纯软件转发根本不扛不住。当时摆在面前的核心矛盾是业务虚拟机需要尽量多的物理核而虚拟网络这一层又不得不消耗大量核去做报文处理。我们最终的决定是把网络快路径全部“挪”到可编程网卡芯片里让 CPU 只负责管理和控制。如果你正在做云网络、虚拟化平台或者 SmartNIC 相关的技术选型这篇文章里提到的方案拆解、落地方案和线上踩坑记录应该能帮你少走不少弯路。我会尽量把每个关键决策背后的原因也讲清楚毕竟选型只是开始真正的挑战在后面的稳定性、可运维性和性能调优。1. 为什么云网络一定要用可编程网卡1.1 软件转发模式的极限传统虚拟网络的转发路径大致长这样物理网卡收到报文之后通过中断或者轮询把数据送到内核协议栈Open vSwitch后面统称 OVS的内核模块拿到报文后先解析头部字段再查询流表命中了就执行动作比如剥掉 VLAN、封装 VxLAN、改 MAC、转发到某个虚拟端口。动作执行完数据再交给虚拟机对应的 virtio 队列。这套模型在小规模场景下没问题但一旦带宽上来就暴露两个死穴。第一个是 CPU 消耗一个网卡中断上来CPU 要么进硬中断要么进软中断每个报文都伴随着一次完整的流表查找、动作执行和 skb 处理。按我们实测的数据纯软件 OVS 处理单条 100G 链路的线速流量至少需要消耗两个以上的物理核如果叠加安全组、NAT、QoS 这些功能核数还要往上加。第二个是流表容量云上租户多、网段杂几十万条流表项是常态软件流表查得越深CPU 的 cache miss 就越严重最终把 CPU 拖垮。所以你去看任何一家云平台只要规模稍微大一点都会面对同一个问题物理网卡越来越快CPU 频率却不怎么涨虚拟网络必须找到新的出路。出路的方向也很明确就是把“每个报文都要经过 CPU 查表转发”这件事尽量挪给硬件去做。1.2 可编程网卡到底“可编程”在哪里很多人第一次听到可编程网卡会以为它是一块 FPGA 网卡其实不完全是。可编程网卡芯片通常是 ASIC 加可编程报文处理流水线的组合。ASIC 负责高速转发流水线部分允许你用类 C 语言、P4 或者厂商的微码去定义查表字段、匹配逻辑、执行动作。它和普通网卡的本质区别在于普通网卡只能做固定功能的卸载比如 RSS 哈希、校验和计算、TSO 分片可编程网卡能做的是“规则级”的卸载。你可以把一条 OVS 流表规则下发给它比如“匹配外层 VxLAN VNI1000 和内层五元组动作是剥掉隧道头送去虚拟机的第一个队列”网卡芯片直接按这条规则处理后续所有同流报文CPU 全程不参与。这里有个很关键的认知硬件卸载不是“全量卸载”。真实场景中可编程网卡的规则存储空间是有限的一般只能容纳几十万条表项。所以现在的做法是把规则分两级热流量对应的规则放在网卡硬件里冷流量和新流量依然走 CPU 软件慢路径软件学习到这条规则之后再把它编译下发到硬件。这个思路跟 CPU 的 Cache 分层很像你不可能让 Cache 装下所有内存数据但你可以让最热的数据待在最靠近执行单元的地方。2. 可编程网卡的技术路线与选型分析2.1 三条主流方案网卡芯片级可编程方案大致有三条路线FPGA、ASIC 加可编程流水线、多核 SoC。三条路线没有绝对的好坏关键看你想在哪个环境里用。方案核心优势明显短板适用场景FPGA 网卡逻辑可重写适合功能快速迭代定制程度高功耗高、单卡价格高、开发门槛高、时延不如 ASIC 稳定新产品期的小规模部署、专用功能验证ASIC 可编程流水线吞吐大、时延低、功耗控制好、规模化成本低一旦流片后逻辑固定新功能要靠微码弥补迭代慢大规模云网络、流量模型相对稳定的场景多核 SoC 网卡完全可编程生态接近通用 CPUSDK 成熟带宽上不去功耗高复杂包处理时延偏大轻量级虚拟化、管理面处理、控制面代劳我们当时最纠结的是 FPGA 和多核 SoC因为大家都希望“灵活”。但最后真正落地的反而是 ASIC 可编程流水线理由很简单云网络的流量模型一旦稳定下来更需要的是高吞吐和低时延而不是无休止的功能堆叠。而且现在 ASIC 方案也支持底层微码升级并非完全不可迭代。2.2 落地选型的几个关键判断选型时我们定了四个硬性标准你可以直接拿去复用。第一是生态兼容性。这个最关键。选一块再强的网卡如果驱动和 OVS 的对接很费劲上线就是灾难。我们当时要求厂商必须能跑官方的 OVS 版本还要能通过一整套虚拟网络功能用例包括 VxLAN 封装解封装、安全组 ACL、流表老化、端口镜像。第二是上行生态的开放性。简单说就是控制面不能锁死在厂商自己的管理接口上。我们要求它至少支持标准化的流表下发通道方便我们自研的上层控制器统一管理。过于封闭的方案初期看着好用后期每加一个功能都要找厂商会拖慢节奏。第三是 RDMA 支持能力。因为云平台不只是跑 TCP 业务GPU 集群、分布式存储、高性能数据库都开始往 RDMA 迁移。可编程网卡如果只有网络卸载能力而不支持 RoCEv2后面还得再插卡不如一次到位。第四是大规模运维能力。包括驱动稳定性、硬件计数器完整度、是否有故障快速定位工具、是否有热升级机制。实验室里再好看的数据放到几百台宿主机上跑都会现原形。我们最后选的是某款商用可编程网卡芯片它的匹配动作流水设计很接近 OVS 的逻辑而且对 VF 和 SF 的规格支持很完善后面做虚拟机无感接入时帮了大忙。3. 核心机制拆解从硬件卸载到虚拟网络加速3.1 OVS 快路径卸载的实现思路OVS 卸载不只是简单地“把 flow 推给网卡”。真正做起来要解决几个问题。第一是规则格式转换。OVS 里的 flow 匹配字段包括 in_port、二层 MAC、VLAN、三层 IP、四层端口以及 VxLAN 的 VNI动作包括 strip_vlan、push_vlan、decapsulate、encapsulate、output。可编程网卡芯片虽然支持类似的 Match-Action 表但字段编码和优先级策略不一定一致。我们实际上是做了一层编译转换把软件侧的 OpenFlow 规则翻译成网卡芯片的匹配条目和动作描述。第二是慢路径与快路径的配合。OVS 慢路径收到新流后会在用户态编译出一条硬件规则下发给网卡此后这条流的报文走硬件。网卡上的规则有老化机制如果一段时间没有命中会通知软件删除对应的软表项避免状态不一致。第三是流表一致性问题。虚拟机热迁移之后旧宿主机上的硬件流表和新宿主机上的表项必须保持同步。我们当时的做法是给每台宿主机的网卡驱动增加了一个订阅通道控制面删除 VM 时往下发一条全局清理指令同时把热迁移触发的流表重建动作纳入统一事务。这个阶段最容易踩的坑是“规则下发风暴”。设想一下一个新建的 VPC 网络里突然跑起批量任务几万条新流在几秒内同时触发慢路径CPU 直接被打满。后来我们把规则下发做成了带优先级的队列新流慢路径只做最小限度的匹配动作把真正费时的动作留给硬件异步完成。3.2 vDPA 让虚拟机无感接入硬件网络硬件卸载做好了虚拟机怎么接入又是一个问题。总不能给每台虚拟机都直通一个 VF那样虽然性能最好但会丢掉热迁移、QoS、流量监控这些云平台的基本功。我们最后采用的是 vDPA 方案。vDPA 的意思是 vhost Data Path Acceleration它可以在保持 virtio 语义不变的前提下让虚拟机的数据路径直接穿透到硬件。虚拟机里还是标准 virtio-net 驱动但宿主机的 vhost 后端已经替换成硬件网卡的数据面virtio 的收发包操作直接由网卡处理。这个方案的精妙之处在于虚拟机无感驱动不用改云平台的控制流程也不用变。只是原来由宿主机 CPU 做的数据拷贝和转发动作全部下沉到硬件里完成。从运维角度讲vDPA 也让我们保留了 hot-plug、热迁移和设备解绑的能力这点比 SRIOV 直通省心太多。具体实现时有个细节值得注意virtio ring 的地址需要让网卡硬件能直接访问。我们要在初始化阶段把虚拟机的 DMA 区域卫生映射到网卡能看到的地址空间这背后涉及到 IOMMU 和页表的联动如果配置不对会出现间歇性的丢包或者虚拟机网卡无响应。我们上线前专门做了一轮跨厂商的内存映射兼容性测试才敢大规模推开。3.3 RDMA、无损网络与存储卸载可编程网卡芯片的另一个大用武之地是 RDMA 网络。为什么要做 RDMA因为越来越多的内部业务开始追求微秒级时延普通 TCP 协议栈已经跟不上节奏。RoCEv2 是最主流的低成本方案它本质上是把 RDMA 报文封装在 UDP 里数据路径仍然由可编程网卡芯片的硬件处理。RDMA 网络要稳定必须做到无损。这里涉及两个关键机制一个是以 PFC优先级流控为基础的链路级流控另一个是 ECN 显式拥塞通知。PFC 处理的是某个优先级队列即将溢出时让对端暂停发送ECN 处理的是交换机或网卡检测到拥塞时在报文里打上标记让接收端反馈给发送端降低速率。这套机制在实验室里很好跑上了现网就有各种微妙的坑。比如 ECN 阈值设置太激进正常大流也会被降速吞吐突然掉一半PFC 的优先级队列如果和普通业务共用一个队列还容易出现队头阻塞。可编程网卡在这里的价值是我们可以在报文进 VF 之前用硬件规则对不同的 RDMA 流做精细的分类把 PFC 的适用范围控制得更小而不是整个链路一刀切。存储卸载也是我们后面才真正拿到的红利。NVMe over Fabric 跑在 RoCEv2 上之后存储节点原本需要消耗 CPU 去处理的 iSCSI 或者 NVMe 命令现在大部分由可编程网卡芯片在数据路径上卸载掉了。单节点 CPU 占用明显下降存储集群的性能天花板又往上抬了一截。4. 落地实操架构、流程与调优4.1 控制面与数据面的总体架构整个系统可以简化为三层上层是云平台网络控制器中间是宿主机网卡驱动和用户态管理组件底层是可编程网卡芯片。控制面通过标准接口统一管理所有宿主机的转发规则数据面则全部依赖网卡硬件。在宿主机内部物理网卡的 PF 被切分成多个 VF 或 SF每个租户的虚拟机绑定到独立的 VF 上租户间的隔离在硬件侧天然完成。上层控制器发布规则时会指定“哪个 VF、哪条流、什么动作”网卡驱动收到后把规则写入芯片的匹配动作表。所有统计计数和老化信息也由驱动定期上报给控制器方便上层去做 QoS、审计和问题诊断。架构上有个比较微妙的设计我们保留了 OVS 作为“慢路径管理者”的角色因为完全甩掉 OVS 不现实。OVS 原来是做所有转发决策的现在它的定位变成了“规则编译器”和“异常处理器”。硬件处理不了的报文或规则查不到的新流全部由慢路径接管处理后把规则交给硬件。这样一来云平台现有的 OpenFlow 生态还能继续用同时硬件只负责最核心的转发动作。4.2 部署、灰度与回退上线方式没有选择全量切换而是分了三步走的灰度策略。第一步是小范围低负载验证。先挑几台 CPU 资源紧张的宿主机开启硬件卸载功能跑现有的业务镜像观察转发面是否正常。我们重点关注四个指标PPS、时延、CPU 占用、错误计数。第二步是放大流量验证。这一步会故意压入大流量看网卡芯片在接近满负载时是否出现流表溢出、硬件丢包或统计失真。那个阶段我们跑了不少 PPS 压测比较硬件模式和软件模式在丢包率上的差异同时也验证规则删除、流老化这些常规流程是否正常。第三步才是按机房、按 VPC 分批切流。切流顺序遵循“先用后重”先切低优先级的离线业务再切在线业务最后才切核心数据库和网关。每一批切完之后观察 24 小时遇到异常立刻回退。回退机制是提前压轴的如果硬件卸载出现严重问题我们只需把宿主机的转发模式切回软件 datapath所有规则重新回到 OVS 软件层执行硬件规则全部冻结并清空。这个过程中业务会短暂抖动几秒但相比整个物理网络不可用已经是很低的代价。4.3 性能调优的关键参数落地调优阶段有几个参数值得反复打磨。第一个是队列数。可编程网卡芯片的每个 VF 都支持多个 RSS 队列队列数的设置直接决定单 VF 的并发收包能力。我们最初按默认 4 队列跑性能瓶颈出现在某个高负载生产 VM 上后来改成 16 队列并绑定到不同的物理核效果立竿见影。需要注意的是队列数并非越大越好队列过多会导致驱动和硬件的中断处理开销变大小包场景反而变慢。第二个是 MTU 的联动。云上 VPC 默认用 1500 的 MTU但 VxLAN 隧道要额外占 50 字节如果不把宿主机的物理口 MTU 调大大包就会分片性能急剧下降。我们最后的做法是物理网卡 MTU 统一设成 1550 以上虚拟机内部仍然保持 1500 的标准值这样既兼容业务又避免隧道分片。第三个是拥塞控制的参数。RDMA 业务上线时ECN 和 PFC 的阈值必须针对不同链路分别调。太敏感会让带宽利用率下降太迟钝又会真的丢包。我们当时用故障注入的方式人为制造拥塞观察网卡自带的流量管理计数器反复调参才慢慢找到平衡点。5. 线上问题排查与踩坑实录5.1 常见问题速查表现象可能原因排查方法解决建议硬件规则频繁 missPPS 不达标流表容量被占满或哈希冲突严重查网卡硬件 flow 使用率、miss 计数上调硬件表容量合理规划可缓存规则分流到慢路径VM 网络通但不稳定偶发丢包vDPA 内存映射配置错误或 IOMMU 页表异常看宿主机 dmesg 报错、网卡错误计数重新绑定 DMA 区域改为连续大页分配热迁移后 VM 网络不通流表未随 VM 迁移做同步清理对比新旧宿主机规则列表控制面统一处理流表迁移迁移前下发清理指令RDMA 大流吞吐骤降ECN 阈值过激或 PFC 与业务队列共用检查 ECN 标记计数、PFC 暂停帧统计调整阈值把 RDMA 优先级单独隔离驱动升级后性能下降新驱动默认参数与硬件流水线不匹配逐项对比驱动推荐值与上线值约束驱动版本升级前做回归压测报文在硬件侧被丢但软件计数无异常硬件动作表配置错误或 ACL 规则冲突用硬件计数器定位丢包点检查匹配表的优先级与动作冲突5.2 一次疑似丢包定位实录有一次线上反馈某组高优业务虚机出现秒级抖动ping 测有丢包但宿主机上 OVS 的软件统计完全正常。当时我先怀疑是链路问题后来把网卡硬件计数器全部拉出来翻了一遍才发现问题出在硬件规则优先级上。那条云主机的高优业务走了硬件快路径但因为它的五元组匹配规则优先级定义得不够高恰好被另一条更泛化的 ACL 规则抢先匹配动作是丢弃。这种规则冲突在软件模式下很容易被发现因为软件会打印日志但硬件规则是静默执行如果不看硬件统计根本不知道有报文被丢弃。解决办法是重新规划匹配规则的优先级编号并统一规范下发的顺序。这次事件之后我们把“硬件 drop 原因计数”纳入所有宿主机的基础监控只要出现 drop 或者 miss 异常立刻告警避免问题发现滞后。5.3 一些提醒和心得第一不要迷信厂商给的参考配置。实验室环境通常只测了理想流型放到真实业务里小包、长短流混合、突发流量这些因素都会带来变量。上线前必须用你自己的业务流量模式去压测而不是拿工具测试一下完事。第二慢路径并不是越少越好。有些人以为硬件卸载率越高越好但其实完全烧掉慢路径很危险。一旦慢路径处理能力不足突发的新流会把 CPU 打满反而拖垮整机。我们实际运行中维持的硬件命中率在 85% 到 95% 之间剩下的流量故意让软件兜底既保证灵活性也避免极端情况下的全盘崩溃。第三硬件计数器和软件计数器要能对应上。如果两边计数的语义不一致排障时会出现“软件说没有、硬件说丢了”这种互相矛盾的局面。我们在开发阶段就花了很多精力统一两边的统计口径包括字节数、包数、丢包原因分类这些都是为后面大规模运维铺路的。6. 沉淀下来的经验这个项目做到后期我最大的体会是可编程网卡真正改变的不是单个报文怎么转发而是整个云网络的运营模型。以前调网络性能要去数 CPU 软中断占比、看 OVS 流表大小现在做这些事的意义下降了很多更多精力花在硬件规则管理、流表优先级设计和新的故障排查手段上。如果让我给正在做类似尝试的团队一句话建议那就是先把回退方案设计清楚再追求性能指标。可编程网卡芯片带来的性能提升是实实在在的但它也引入了一个新的复杂层硬件规则、驱动、虚拟化内存映射、拥塞控制调参每一项都可能在某个时间点出来咬你一口。没有快速回退能力你是不敢在核心业务上开启硬件卸载的。从扩展角度看可编程网卡芯片的潜力还远没有被挖完。我们目前主要做了网络转发和部分 RDMA 卸载存储侧的新特性也刚起步。下一步如果能利用它的可编程流水线把更多安全检测逻辑也做进硬件路径那云网络的性价比还能再上一个台阶。最后分享一个小技巧上线前不管时间多紧一定做一轮“流表漂移测试”——随机创建、删除、迁移大量虚拟网络规则同时跑真实业务流量。很多隐患是在规则变化的瞬间暴露的而不仅仅是持续大流量下。这个测试帮我们提前揪出了好几个硬件规则同步的 bug。踏实压一遍这个比调十次参数都管用。