dist/images/vpcnatgateway/nat-gateway.sh dist/images/vpcnatgateway/lb-svc.sh 这两个脚本在设计上只能使用 /usr/sbin/iptables-legacy 是吧?
不是。两个脚本在设计上并不绑定 legacy,它们只要求 iptables 工具链的命令行接口一致(iptables -t nat -A ...、iptables-save | grep ... 这类标准用法),legacy 和 nft 后端都能正确执行这些命令。
问题出在内核层面:
| 场景 | iptables 后端 | 内核钩子 | 结果 |
|---|---|---|---|
| Alpine (原 Dockerfile) | 脚本检测后显式用 iptables-legacy | 旧内核两套都走 | 正常 |
| Ubuntu 24.04 未改 alternatives | 默认 iptables-nft | nftables | 正常(nft 写 nft 读) |
| Ubuntu 24.04 脚本检测走了 legacy | iptables-legacy | 新内核优先 nftables | 规则失效 |
所以真正的坑是:nat-gateway.sh 里的检测逻辑在容器内 iptables-legacy -t nat -S INPUT 1 可能成功(宿主机内核加载了 ip_tables 模块),脚本切到 legacy 写规则,但新内核数据路径只看 nftables 表。
Dockerfile.ubuntu 里 update-alternatives --set iptables /usr/sbin/iptables-legacy 解决的是:让 iptables 和 iptables-legacy 指向同一个二进制,脚本无论走哪条分支都用 legacy,内核侧通过 ip_tables 模块处理 legacy 规则(容器共享宿主机内核,宿主机通常会加载该模块)。
如果未来想让脚本同时兼容 nft 后端,只需要去掉 Dockerfile 里的 update-alternatives 并删除脚本中 iptables-legacy 的检测分支,让 iptables_cmd 始终用系统默认即可,不需要改脚本的 iptables 规则操作逻辑。
从你提供的 nat-gateway.sh 脚本和 Dockerfile 来看,问题的原因完全闭环了:这是一个典型的“新镜像跑在了老逻辑”上的兼容性故障。
1. 致命原因:Ubuntu 24.04 的默认行为
你的 Dockerfile 使用了 FROM ubuntu:24.04。
-
新特性: 在 Ubuntu 24.04 (Noble Numbat) 中,系统的
iptables命令默认链接到 iptables-nft。 -
脚本逻辑: 你的脚本中有这样一段逻辑:
Bash
iptables_cmd=$(which iptables) if iptables-legacy -t nat -S INPUT 1 2>/dev/null; then # use iptables-legacy for centos 7 iptables_cmd=$(which iptables-legacy) ... fi这段逻辑设计的初衷是检测系统是否偏好
legacy。但在 Ubuntu 24.04 镜像里,虽然安装了iptables包(包含 legacy 和 nft),但脚本的检测逻辑可能失效,或者更糟糕的是:它虽然识别并使用了iptables-legacy去写入规则,但 Ubuntu 24.04 的内核协议栈默认只通过 nftables 钩子处理流量。
2. 为什么规则“完全无法命中”?
在 Ubuntu 24.04 这种较新的系统里,内核往往不再加载 ip_tables (Legacy) 模块,而是全面转向 nf_tables。
- 脚本: 将 DNAT 规则强行写入了
iptables-legacy表。 - 内核: 只盯着
nftables的链看。 - 错位: 你的规则在 Legacy 表里静静躺着,而流量在 NFT 链里穿行,因为 NFT 链里是空的,所以没有执行任何 NAT 动作,包直接撞到了本地 22 端口,由于没进程监听,内核回了 RST。
3. 如何修复?
方案 A:在 Dockerfile 中强制切换系统默认模式(推荐)
在 Dockerfile 的 RUN 指令中,明确设置容器内的 iptables 优先级,让 iptables 命令直接指向 legacy。
Dockerfile
RUN update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
root@jfcs1001:~# kgp |grep fip-subnet-69897ff101ca5d975cb0fdbb
kube-system vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0 1/1 Running 0 94s 10.1.255.254 jfcs1003 <none> <none>
root@jfcs1001:~# k exec -it -n kube-system vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0 -- bash
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: net1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP group default qlen 1000
link/ether fa:83:79:f4:b5:de brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 183.240.180.136/27 scope global net1
valid_lft forever preferred_lft forever
inet6 fe80::f883:79ff:fef4:b5de/64 scope link
valid_lft forever preferred_lft forever
3: ifb-net1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc htb state UNKNOWN group default qlen 1000
link/ether b2:03:eb:47:1c:ef brd ff:ff:ff:ff:ff:ff
inet6 fe80::b003:ebff:fe47:1cef/64 scope link
valid_lft forever preferred_lft forever
323: eth0@if324: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default
link/ether d2:5e:08:c7:02:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.255.254/16 brd 10.1.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::d05e:8ff:fec7:2b5/64 scope link
valid_lft forever preferred_lft forever
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 183.240.180.129 0.0.0.0 UG 0 0 0 net1
10.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
10.233.0.0 10.1.0.1 255.255.0.0 UG 0 0 0 eth0
100.121.68.26 0.0.0.0 255.255.255.255 UH 0 0 0 net1
183.240.180.128 0.0.0.0 255.255.255.224 U 0 0 0 net1
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-legacy-save
# Generated by iptables-save v1.8.10 on Wed Feb 11 12:47:38 2026
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DNAT_FILTER - [0:0]
:EXCLUSIVE_DNAT - [0:0]
:EXCLUSIVE_SNAT - [0:0]
:SHARED_DNAT - [0:0]
:SHARED_SNAT - [0:0]
:SNAT_FILTER - [0:0]
-A PREROUTING -j DNAT_FILTER
-A POSTROUTING -j SNAT_FILTER
-A DNAT_FILTER -j EXCLUSIVE_DNAT
-A DNAT_FILTER -j SHARED_DNAT
-A EXCLUSIVE_DNAT -d 183.240.180.136/32 -j DNAT --to-destination 10.1.0.2
-A EXCLUSIVE_SNAT -s 10.1.0.2/32 -j SNAT --to-source 183.240.180.136
-A SNAT_FILTER -j EXCLUSIVE_SNAT
-A SNAT_FILTER -j SHARED_SNAT
COMMIT
# Completed on Wed Feb 11 12:47:38 2026
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# telnet 10.1.0.2 22
Trying 10.1.0.2...
Connected to 10.1.0.2.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.11
^]
telnet>
Connection closed.
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# telnet 183.240.180.136 22
Trying 183.240.180.136...
telnet: Unable to connect to remote host: Connection refused
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# ping 183.240.180.136
PING 183.240.180.136 (183.240.180.136) 56(84) bytes of data.
64 bytes from 183.240.180.136: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 183.240.180.136: icmp_seq=2 ttl=64 time=0.043 ms
^C
--- 183.240.180.136 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1025ms
rtt min/avg/max/mdev = 0.037/0.040/0.043/0.003 ms
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# arping 183.240.180.136
Interface "lo" is not ARPable
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# tcpdump -i any port 22 -netvv
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
net1 In ifindex 2 2a:e5:0d:36:50:72 ethertype IPv4 (0x0800), length 72: (tos 0x10, ttl 64, id 7599, offset 0, flags [DF], proto TCP (6), length 52)
100.121.68.26.13128 > 183.240.180.136.22: Flags [S], cksum 0x1533 (incorrect -> 0x8fff), seq 2525037877, win 64240, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
ifb-net1 Out ifindex 3 2a:e5:0d:36:50:72 ethertype IPv4 (0x0800), length 72: (tos 0x10, ttl 64, id 7599, offset 0, flags [DF], proto TCP (6), length 52)
100.121.68.26.13128 > 183.240.180.136.22: Flags [S], cksum 0x1533 (incorrect -> 0x8fff), seq 2525037877, win 64240, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
net1 Out ifindex 2 fa:83:79:f4:b5:de ethertype IPv4 (0x0800), length 60: (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
183.240.180.136.22 > 100.121.68.26.13128: Flags [R.], cksum 0xcbae (correct), seq 0, ack 2525037878, win 0, length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 241, id 54321, offset 0, flags [none], proto TCP (6), length 40)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x1e7e (correct), seq 2509600692, win 65535, length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 241, id 54321, offset 0, flags [none], proto TCP (6), length 40)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x1e7e (correct), seq 2509600692, win 65535, length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x078a (correct), seq 2509600692, win 65535, options [mss 1260], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x078a (correct), seq 2509600692, win 65535, options [mss 1260], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x06c2 (correct), seq 2509600692, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x06c2 (correct), seq 2509600692, win 65535, options [mss 1460], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x06c2 (correct), seq 2509600692, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 239, id 54321, offset 0, flags [none], proto TCP (6), length 44)
152.42.131.4.52436 > 103.129.52.128.22: Flags [S], cksum 0x06c2 (correct), seq 2509600692, win 65535, options [mss 1460], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 237, id 54321, offset 0, flags [none], proto TCP (6), length 40)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xd4f1 (correct), seq 529745329, win 65535, length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 237, id 54321, offset 0, flags [none], proto TCP (6), length 40)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xd4f1 (correct), seq 529745329, win 65535, length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbdfd (correct), seq 529745329, win 65535, options [mss 1260], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbdfd (correct), seq 529745329, win 65535, options [mss 1260], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbd35 (correct), seq 529745329, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbd35 (correct), seq 529745329, win 65535, options [mss 1460], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbd35 (correct), seq 529745329, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x74, ttl 235, id 54321, offset 0, flags [none], proto TCP (6), length 44)
80.94.92.168.43295 > 120.240.166.128.22: Flags [S], cksum 0xbd35 (correct), seq 529745329, win 65535, options [mss 1460], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 234, id 54321, offset 0, flags [none], proto TCP (6), length 40)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x5a0d (correct), seq 667067961, win 65535, length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 234, id 54321, offset 0, flags [none], proto TCP (6), length 40)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x5a0d (correct), seq 667067961, win 65535, length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4319 (correct), seq 667067961, win 65535, options [mss 1260], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4319 (correct), seq 667067961, win 65535, options [mss 1260], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4251 (correct), seq 667067961, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4251 (correct), seq 667067961, win 65535, options [mss 1460], length 0
net1 B ifindex 2 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4251 (correct), seq 667067961, win 65535, options [mss 1460], length 0
ifb-net1 Out ifindex 3 20:0b:c7:3b:ec:16 ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 232, id 54321, offset 0, flags [none], proto TCP (6), length 44)
178.128.248.99.40912 > 163.142.153.128.22: Flags [S], cksum 0x4251 (correct), seq 667067961, win 65535, options [mss 1460], length 0
^C
27 packets captured
27 packets received by filter
0 packets dropped by kernel
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: net1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP group default qlen 1000
link/ether fa:83:79:f4:b5:de brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 183.240.180.136/27 scope global net1
valid_lft forever preferred_lft forever
inet6 fe80::f883:79ff:fef4:b5de/64 scope link
valid_lft forever preferred_lft forever
3: ifb-net1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc htb state UNKNOWN group default qlen 1000
link/ether b2:03:eb:47:1c:ef brd ff:ff:ff:ff:ff:ff
inet6 fe80::b003:ebff:fe47:1cef/64 scope link
valid_lft forever preferred_lft forever
323: eth0@if324: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default
link/ether d2:5e:08:c7:02:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.255.254/16 brd 10.1.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::d05e:8ff:fec7:2b5/64 scope link
valid_lft forever preferred_lft forever
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# root@jfcs1001:~# k exec -it -n kube-system vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0 -- bash
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: net1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP group default qlen 1000
link/ether fa:83:79:f4:b5:de brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 183.240.180.136/27 scope global net1
valid_lft forever preferred_lft forever
inet6 fe80::f883:79ff:fef4:b5de/64 scope link
valid_lft forever preferred_lft forever
3: ifb-net1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc htb state UNKNOWN group default qlen 1000
link/ether b2:03:eb:47:1c:ef brd ff:ff:ff:ff:ff:ff
inet6 fe80::b003:ebff:fe47:1cef/64 scope link
valid_lft forever preferred_lft forever
323: eth0@if324: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default
link/ether d2:5e:08:c7:02:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.255.254/16 brd 10.1.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::d05e:8ff:fec7:2b5/64 scope link
valid_lft forever preferred_lft forever
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 183.240.180.129 0.0.0.0 UG 0 0 0 net1
10.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
10.233.0.0 10.1.0.1 255.255.0.0 UG 0 0 0 eth0
100.121.68.26 0.0.0.0 255.255.255.255 UH 0 0 0 net1
183.240.180.128 0.0.0.0 255.255.255.224 U 0 0 0 net1
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-legacy-save
# Generated by iptables-save v1.8.10 on Wed Feb 11 12:47:38 2026
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DNAT_FILTER - [0:0]
:EXCLUSIVE_DNAT - [0:0]
:EXCLUSIVE_SNAT - [0:0]
:SHARED_DNAT - [0:0]
:SHARED_SNAT - [0:0]
:SNAT_FILTER - [0:0]
-A PREROUTING -j DNAT_FILTER
-A POSTROUTING -j SNAT_FILTER
-A DNAT_FILTER -j EXCLUSIVE_DNAT
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#^Cd 0ueue state UP group default000n 65535, options [mss 1460], length 0TCP (6), length 44)),wscale 7], length 0
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# sysctl -a | grep "\.rp_filter"
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.eth0.rp_filter = 2
net.ipv4.conf.ifb-net1.rp_filter = 2
net.ipv4.conf.lo.rp_filter = 2
net.ipv4.conf.net1.rp_filter = 2
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-nft
iptables v1.8.10 (nf_tables): no command specified
Try `iptables -h' or 'iptables --help' for more information.
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-nft
iptables-nft iptables-nft-restore iptables-nft-save
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-nft-save
# Warning: iptables-legacy tables present, use iptables-legacy-save to see them
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# watch -n 1 "iptables -t nat -L EXCLUSIVE_DNAT -v -n"
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# ss -tunlp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# watch -n 1 "iptables-legacy -t nat -L EXCLUSIVE_DNAT -v -n"
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn# iptables-legacy -t nat -L EXCLUSIVE_DNAT -v -n
Chain EXCLUSIVE_DNAT (1 references)
pkts bytes target prot opt in out source destination
0 0 DNAT 0 -- * * 0.0.0.0/0 183.240.180.136 to:10.1.0.2
root@vpc-nat-gw-fip-subnet-69897ff101ca5d975cb0fdbb-0:/kube-ovn#
根据你提供的一系列终端输出、抓包数据和截图,当前的问题可以总结为:流量路径与规则链条的“空间错位” ,导致 DNAT 规则虽然存在,但实际上处于“离线”状态。
以下是详细的问题总结:
1. 核心矛盾:iptables 后端双版本冲突
这是问题的根源。你的系统内同时存在两个 iptables 后端:Legacy(传统模式)和 NFT(nf_tables 模式)。
- 规则在 Legacy: Kube-OVN 生成的 DNAT 规则(如
EXCLUSIVE_DNAT链)全都在iptables-legacy表中。 - 流量走 NFT: 内核当前默认使用
nftables处理数据包。当你执行iptables-nft-save时,发现里面几乎是空的,且系统提示存在 Legacy 表警告。 - 结果: 进入系统的流量在
nftables层级寻找规则,匹配不到任何 DNAT 指令,因此直接跳过 NAT 逻辑,进入了本地(Local Input)流程。
2. 故障表现:为何 Telnet 失败而 Ping 成功?
-
外部访问 (Telnet/SSH):
- 外部包(100.121.68.26)到达接口
net1,目标 IP 是网关 IP183.240.180.136。 - 因为 DNAT 没生效,系统认为这个包是发给“网关自己”的。
- 网关 Pod 本身没有监听 22 端口,所以内核协议栈直接回了一个 RST(Reset)包。这解释了你在
tcpdump中看到的Flags [R.]。
- 外部包(100.121.68.26)到达接口
-
内部测试 (Ping/Local Telnet):
- 你在 Pod 内部
telnet 10.1.0.2能通,是因为这走的是纯内网路由,不涉及net1的 DNAT。 ping 183.240.180.136能通,是因为 ICMP 包被本地回环或接口地址直接响应了,不需要经过 DNAT 转换。
- 你在 Pod 内部
3. 数据链路确认:规则命中率为零
通过你上传的 watch 截图可以确认:
- 命中数为 0: 在
iptables-legacy视图下,EXCLUSIVE_DNAT链中的pkts(包数)和bytes(字节数)始终为 0。 - 链路断裂: 流量在
PREROUTING阶段就没有被正确引导进DNAT_FILTER链,或者是因为内核压根没去查 Legacy 表。
4. 潜在的次要阻碍:RP Filter 限制
虽然不是主因,但你的网络配置中 net1 接口的 rp_filter(反向路径过滤)设置为 2(松散模式)。
- 在某些复杂的 VPC 网络(如 Kube-OVN 这种多接口环境)中,即便 DNAT 生效,如果内核认为回程路由不一致,仍可能在后期丢包。
结论与建议
当前问题的实质是 Kube-OVN 写入的规则位置(Legacy)与内核当前生效的规则引擎(NFT)不匹配。
建议下一步操作:
- 强制同步: 尝试将规则手动写入
iptables-nft看看流量计数是否开始跳动。 - 后端切换: 在容器内尝试执行
update-alternatives --set iptables /usr/sbin/iptables-legacy,迫使系统工具链统一。 - CNI 检查: 检查该节点的
kube-proxy或kube-ovn-cni是否使用了混合模式,通常建议在集群范围内统一iptables模式。
你想让我帮你生成一段可以直接在 nftables 模式下生效的临时 DNAT 规则来测试吗?