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. 部署方式
- 编译生成
kube_ovn_fastpath.ko - 复制到每个节点的 tmp 目录
kube-ovn-cni自动加载该模块- 通过
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_hooksnf_unregister_net_hooksregister_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
自动化建议
如果需要支持多个内核版本,可以:
-
使用 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 -
或者预编译多个版本,按内核版本分发对应的
.ko文件