vrf创建后路由表为空是因为它仅是路由域容器,不自动导入路由;需手动绑定接口并用ip route add显式添加路由条目,否则table始终为空。

为什么 vrf 创建后路由表为空?
Linux 的 vrf 本身不自动导入任何路由,它只是个路由域容器,必须手动把接口绑定进去、再把路由加进去,否则就是空壳子。
-
ip link add vrf-blue type vrf table 100只建了 VRF 设备和关联的路由表,没动任何路由条目 - 必须用
ip route add table 100 default via 192.168.1.1这类命令显式添加路由,否则ip route show table 100永远为空 - 如果绑定了物理接口(如
eth0),还要确保该接口已up,且未被其他路由表“抢先”接管流量
如何让进程走指定 vrf?
不能靠改进程配置或环境变量,得用 ip vrf exec 启动——这是唯一可靠方式。直接 curl 或 ping 默认走主路由表,跟 VRF 无关。
-
ip vrf exec vrf-blue ping 8.8.8.8才会查table 100的路由并从绑定接口出 - 想让服务(比如
nginx)跑在 VRF 里,得写成ip vrf exec vrf-blue nginx -g "daemon off;" - 注意:
ip vrf exec会 fork 新进程并设置 netns 和路由查找上下文,但不会修改进程内已打开的 socket,所以服务启动前就得进 VRF
vrf 绑定接口后为啥不通?
常见原因是接口没正确启用策略路由(policy routing),或者底层设备不支持 L3 forwarding in VRF context。
- 必须执行
ip link set dev eth0 master vrf-blue,不是ip addr add那种地址绑定 - 绑定后,
eth0的所有三层流量都由 VRF 路由表控制,但二层转发仍需开启:sysctl -w net.ipv4.conf.eth0.forwarding=1 - 某些网卡驱动(尤其虚拟化环境中的
virtio_net)对 VRF 的 L3 offload 支持不全,可临时关掉:ethtool -K eth0 tx off rx off
多个 vrf 之间能互通吗?
默认完全隔离,连 ARP 都不跨 VRF。想互通必须显式配置路由 + 策略规则,而且要小心环路和策略优先级冲突。
- 例如让
vrf-blue(table 100)访问vrf-red(table 200),得在 100 表里加:ip route add 10.10.2.0/24 via 10.10.1.254 dev vrf-blue,同时确保 10.10.1.254 是个真实存在的三层网关接口 - 更安全的做法是用独立的“骨干 VRF”做中转,避免直连路由导致的策略混乱
- 别忘了检查
rp_filter:多个 VRF 共享物理接口时,net.ipv4.conf.all.rp_filter=1会误判反向路径,建议设为2(loose mode)
真正麻烦的不是创建 VRF,而是搞清每个接口的 master 关系、每张路由表的策略规则、以及 rp_filter 和 forwarding 在多 VRF 下的组合行为——这些地方一错,就只能抓包看哪个环节丢包了。










