我在 Windows 10 主机上有一个 UDP 服务器,位于固定端口(假设为 1234)。我只想在这个服务器和 Docker(基于 Debian)容器(Docker 版本 20.10.6)中的客户端之间建立通信。这是使用 WSL2。
请注意,我的 UDP 客户端不能使用特定的源端口,而是采用随机端口。
使用默认的 docker 网络选项 ( docker run --net bridge ...
),docker 容器172.17.0.2
在其eth0@if10
接口上有 IP 地址。Windows 主机172.27.192.1
在其Ethernet adapter vEthernet (WSL)
接口上有 IP 地址。UDP 数据包到达服务器,服务器回复,但收到 ICMP消息。这是因为数据包在其路径的某处已被重写。Docker容器内接口port unreachable
上看到的数据包是正常的: 。从 Windows 主机,我在 Wireshark 上看到它们(以及来自服务器的回复)。但在那里,它们已被重写为!因此回复永远不会到达容器。eth0@if10
172.17.0.2:some random port => 172.27.192.1:1234
Adapter for loopback traffic capture
172.27.192.1:another port => 172.27.192.1:1234
让我感到困惑的是,TCP 和 ping(从容器到主机)工作正常。数据包被完全重写……但它们安全地返回容器。
现在我想尝试禁用此 NAT,但这很复杂,因为如果我从 Windows 主机向容器 ( 172.17.0.2
) 发送数据包,数据包将通过以太网接口发送并丢失。我尝试添加静态路由来告诉应该172.17.0.0/24
通过172.27.192.1
网关,但随后我看到网关发送 ARP 数据包询问谁有172.17.0.2
。
使用docker run --net host ...
基本上存在同样的问题。我从这个容器看到主机的 IP 地址是192.168.65.2
(带有dig host.docker.internal
)。我还看到数据包将采用接口eth0
。观察这个接口和Adapter for loopback traffic capture
主机,我看到数据包从 重写为192.168.65.3:some random port => 192.168.65.2:1234
。UDP127.0.0.1:another port => 127.0.0.1:1234
服务器在尝试回复后再次收到destination unreachable
ICMP 消息。