kubeovn LS_DNAT_MOD_DL_DST 参数

35 阅读5分钟

非常好的问题,这个参数其实是 OVN-Kubernetes(或 Kube-OVN)中针对 DNAT(Destination NAT)场景下的一个行为控制开关
我们来从功能、原理和对应的流表行为三个层次详细分析:


🧩 一、参数含义与功能

LS_DNAT_MOD_DL_DST=${LS_DNAT_MOD_DL_DST:-true}
意思是:

当逻辑交换机(Logical Switch)执行 DNAT 操作后,是否要同时 修改以太网帧的目的 MAC 地址(DL_DST)

  • LS_DNAT_MOD_DL_DST=true

    • 在逻辑交换机层面执行 DNAT 后,会 将以太网帧的目标 MAC 地址重写为目标 IP 对应的 MAC 地址
    • 简单说,就是:DNAT 改完 IP 后,顺便把 MAC 也改成正确的目标 MAC
  • LS_DNAT_MOD_DL_DST=false

    • DNAT 只改 IP,不改以太帧的目的 MAC。
    • 这种情况下,后续必须依赖 ARP/ND 或额外流表查找来确定目的 MAC,否则包可能无法正常转发。

🧠 二、原理机制

要理解这个参数的原理,得先看 OVN 的 NAT 实现原理。

1️⃣ DNAT 基本流程

在 OVN 的逻辑流表中,DNAT 通常发生在:

  • ls_in_pre_lbls_in_nat 这类阶段(针对入方向流量)

  • 其行为是:

    ip, ip.dst=<vip> → ip.dst=<real-ip>; next;
    

DNAT 之后,包的 目的 IP 已经被改成了真实后端 Pod 的 IP。
但此时,L2 层(以太头)的目的 MAC 仍然是虚拟 IP 对应的 MAC,而不是 Pod 的 MAC。

2️⃣ 为什么要改 DL_DST?

逻辑交换机做转发是靠匹配 MAC 地址(L2 层)的。
DNAT 后如果不改 dl_dst,OVN 的逻辑交换机就无法正确将包送到真正的 Pod 端口,因为逻辑转发依赖 MAC 匹配(即 LS 中 port 的 lport 对应 MAC)。

所以 LS_DNAT_MOD_DL_DST=true 时,OVN 在 DNAT 规则之后会多加一步:

ip, ip.dst=<real-ip> → ip.dst=<real-ip>; eth.dst=<real-mac>; next;

这一步保证了包能正确被逻辑交换机的 L2 转发表匹配到对应的 Pod port。


⚙️ 三、对应的流表行为(以 OVN-SB dump 举例)

ovn-sbctl dump-flows 中,你能看到类似的条目:

table=17 (ls_in_nat), priority=100,
match=(ip && ip4.dst == 10.96.0.10),
actions=ip4.dst=10.244.0.5; eth.dst=00:00:00:aa:bb:cc; next;

这个 eth.dst=... 部分,就是受 LS_DNAT_MOD_DL_DST 控制的。

如果你将这个参数设为 false,你会看到流表中只改 IP:

actions=ip4.dst=10.244.0.5; next;

此时,需要依赖后续逻辑阶段(ls_in_l2_lkup)做 ARP 解析或查表。


🔍 四、为什么有时要关闭它?

虽然 LS_DNAT_MOD_DL_DST=true 是默认行为(正确而高效),
但在某些特殊情况下(例如多层 overlay 或外部网关接入),可能希望 由外部路由设备来处理 MAC 重写,这时会将其设为 false,避免 OVN 改 MAC。

例如:

  • 某些南北向负载均衡(LB)场景;
  • DNAT 目标是外部路由器,不在逻辑交换机中;
  • 或者希望保留原始 L2 信息以便上层进行跟踪分析。

✅ 五、总结

参数默认值功能原理
LS_DNAT_MOD_DL_DSTtrue控制 DNAT 后是否修改以太帧目的 MAC 地址若为 true,DNAT 同时改 IP 和 MAC,保证包能直接转发到正确 Pod port
原理位置逻辑交换机阶段 (ls_in_nat)修改 ip.dst 后追加 eth.dst 改写避免后续 L2 查找错误或广播

💬 简化总结一句话

LS_DNAT_MOD_DL_DST=true 表示:DNAT 不仅改 IP,也改 MAC,保证包能被逻辑交换机正确送到目的端口。


非常好,这是个关键问题。结论先说:

如果你没有使用 OVN 的 DNAT/LB(即 Logical Router 的 NAT 功能) ,那么
LS_DNAT_MOD_DL_DST 参数即使开启也不会有实际影响,但一般保持默认 true 是安全且推荐的

下面我详细说明原因和内部逻辑——


🧩 一、参数作用范围

LS_DNAT_MOD_DL_DST 只在 逻辑交换机(Logical Switch) pipeline 中的 NAT 相关阶段(通常是 ls_in_nat)生效。
而这个阶段的流表仅在:

  • 逻辑路由器有 DNATload balancer 规则时;
  • 或者开启了南北向 LB(ovn-nbctl lb-add)时,
    才会生成对应的 flow。

所以:

  • 如果你的集群不使用 NAT / LB 功能(也就是纯 VPC 内部二层、三层通信)
    那么这一阶段根本不会有 DNAT 流表被下发。
  • 即使 LS_DNAT_MOD_DL_DST=true,也不会被匹配或执行,逻辑上等于无效。

🧠 二、为什么默认保持 true 是推荐的

虽然在无 NAT 场景下它不起作用,但从体系角度讲:

  1. Kube-OVN 的模板流表逻辑是统一生成的
    LS_DNAT_MOD_DL_DST 的作用是控制模板中是否插入 eth.dst 重写动作。
    即使没有 NAT,模板仍会初始化这个 flag。
  2. 未来扩展时避免问题
    若后续你启用了 LB 或外部入口 NAT(例如 ovn-nbctl lb-add 创建了 service VIP),
    那么若此参数为 false,会导致包在 DNAT 后无法正确转发到 Pod(因为没改 MAC)。
    一般诊断会看到包停在 ls_in_l2_lkup 阶段或被丢弃。
  3. 性能影响可以忽略
    这个 flag 只是控制逻辑流表模板,不增加任何额外流表或匹配负担。

⚙️ 三、对典型场景的建议

场景是否需要开启 LS_DNAT_MOD_DL_DST说明
只使用 OVN 二层/三层转发,不用 NAT/LB可开可关(无影响)不产生 DNAT 流表
使用 OVN 负载均衡(Service VIP)或 EIP DNAT✅ 必须开启否则 DNAT 后 MAC 不改,包无法送达
外部物理网关做 NAT,不用 OVN NAT可关闭避免 OVN 改 MAC 干扰外部路由
混合场景(部分内置 LB,部分外部路由)建议开启保证内部 LB 正常工作

✅ 四、总结结论

条件是否需要
不使用 OVN NAT/LB❌ 不需要(开启也无害)
使用 OVN DNAT/LB(VIP、EIP、ClusterIP)✅ 必须开启
使用外部路由器做 NAT⚙️ 可关闭(避免 MAC 改写)

推荐默认保持 true,即使当前不用 NAT。

因为:

  • 不影响性能;
  • 不干扰非 NAT 流量;
  • 后续启用 LB/NAT 时可直接生效。