kubeovn fast ko

6 阅读2分钟

kubeovn.github.io/docs/v1.15.…

Using "提取网页"

Fetched kubeovn.github.io/docs/v1.15.…

读取

根据文档和代码分析,我来总结 kube_ovn_fastpath.c 的作用:

FastPath 内核模块功能

1. 核心目标

绕过 Netfilter 提升性能。经过性能 Profile,Netfilter 在容器和宿主机上的处理消耗约 20% 的 CPU 资源。FastPath 模块可以:

  • 降低 CPU 消耗
  • 降低网络延迟
  • 提升吞吐量

2. 工作原理

模块在 Netfilter 的 4 个 hook 点 以最高优先级 (NF_IP_PRI_FIRST) 注册 hook 函数:

PRE_ROUTING → LOCAL_IN → LOCAL_OUT → POST_ROUTING

3. 流量处理逻辑

场景条件行为
Geneve 隧道流量state->net == init_net + UDP 端口 6081调用 okfn() 直接转发,返回 NF_STOLEN 绕过后续 Netfilter
STT 隧道流量state->net == init_net + TCP 端口 7471 (非 LOCAL_IN)同上
容器内流量state->net != init_net (非 root network namespace)直接绕过 Netfilter
其他流量宿主机普通流量正常走 Netfilter (NF_ACCEPT)

4. 数据平面流程图

                      Host Network Namespace (init_net)
┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│   Geneve/STT Tunnel Traffic (port 6081/7471)                     │
│   ───────────────────────────────────────────►  NF_STOLEN        │
│                                                 (bypass netfilter)
│   Other Traffic                                                  │
│   ───────────────────────────────────────────►  NF_ACCEPT        │
│                                                 (normal path)    │
└──────────────────────────────────────────────────────────────────┘

                      Container Network Namespace (!= init_net)
┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│   All Traffic                                                    │
│   ───────────────────────────────────────────►  NF_STOLEN        │
│                                                 (bypass netfilter)
└──────────────────────────────────────────────────────────────────┘

5. 部署方式

  1. 编译生成 kube_ovn_fastpath.ko
  2. 复制到每个节点的 tmp 目录
  3. kube-ovn-cni 自动加载该模块
  4. 通过 dmesg 确认加载成功

这是一个典型的 Netfilter bypass 优化方案,针对 OVN overlay 网络的隧道流量和容器流量进行加速。

我想知道我在 5.15.0-94-generic 编译的 kube_ovn_fastpath.ko 是否可以直接用于 5.15.0-46-generic 环境

答案:通常不能直接使用

Linux 内核模块有严格的版本校验机制,即使是 同主版本不同补丁版本(5.15.0-94 vs 5.15.0-46)也会被拒绝加载。

原因分析

1. vermagic 字符串不匹配

内核模块嵌入了编译时的内核版本信息:

# 查看模块的 vermagic
modinfo kube_ovn_fastpath.ko | grep vermagic
# 输出类似: vermagic: 5.15.0-94-generic SMP mod_unload modversions

加载时内核会检查 vermagic 是否与当前运行内核完全匹配。

2. CONFIG_MODVERSIONS (Symbol CRC 校验)

Ubuntu/Debian 的 generic 内核启用了 CONFIG_MODVERSIONS,这会为每个导出符号计算 CRC:

  • nf_register_net_hooks
  • nf_unregister_net_hooks
  • register_pernet_subsys
  • 等等...

不同补丁版本可能因内部结构变化导致 CRC 不一致。

3. 强制加载的风险

虽然可以用 insmod -f 强制加载,但:

可能的后果:
├── 内核结构体大小/布局变化 → 内存越界 → kernel panic
├── 函数签名变化 → 调用失败 → oops
└── 数据结构偏移变化 → 数据损坏

正确做法

必须在目标内核版本上重新编译

# 在 5.15.0-46-generic 环境下
apt install linux-headers-$(uname -r)
cd kube-ovn/fastpath/4.x-6.x
make clean && make

自动化建议

如果需要支持多个内核版本,可以:

  1. 使用 DKMS (Dynamic Kernel Module Support):

    # 自动在内核升级时重新编译
    dkms add ./kube-ovn-fastpath
    dkms build -m kube-ovn-fastpath -v 1.0
    dkms install -m kube-ovn-fastpath -v 1.0
    
  2. 或者预编译多个版本,按内核版本分发对应的 .ko 文件