Linux VRF(Virtual Routing and Forwarding)的多租户网络隔离实现

3次阅读

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

Linux VRF(Virtual Routing and Forwarding)的多租户网络隔离实现

为什么 vrf 创建后路由表为空?

linuxvrf 本身不自动导入任何路由,它只是个路由域容器,必须手动把接口绑定进去、再把路由加进去,否则就是空壳子。

  • 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 启动——这是唯一可靠方式。直接 curlping 默认走主路由表,跟 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_filterforwarding 在多 VRF 下的组合行为——这些地方一错,就只能抓包看哪个环节丢包了。

text=ZqhQzanResources