我正在 AWS ECS 上运行的 Docker 容器(运行 ubuntu 18)中尝试与外部数据中心建立连接。我们已经对问题进行了故障排除,我们认为是本地 Docker 网络添加的额外跃点导致了故障。事实支持了这一点,即从 Docker 主机 EC2 实例成功完成对目标 IP 的 curl 请求,以及从部署到距离目标 IP 少于 33 个跃点的子网时从同一 Docker 容器内部成功完成对目标 IP 的 curl 请求。
traceroute <destination_ip>
当从容器内部运行时,我看到 33 个跳数:
root@1cfbdf43c8f5:~# traceroute -m36 <destination_ip>
traceroute to <destination_ip> (<destination_ip>), 36 hops max, 60 byte packets
1 ip-172-17-0-1.us-east-2.compute.internal (172.17.0.1) 0.039 ms 0.014 ms 0.013 ms
2 ip-10-133-216-197.us-east-2.compute.internal (10.133.216.197) 1.185 ms 1.146 ms 1.107 ms
3 ec2-52-15-0-157.us-east-2.compute.amazonaws.com (52.15.0.157) 8.188 ms ec2-52-15-0-169.us-east-2.compute.amazonaws.com (52.15.0.169) 5.615 ms ec2-52-15-0-161.us-east-2.compute.amazonaws.com (52.15.0.161) 10.227 ms
...
32 <destination_ip> 24.706 ms 24.584 ms 24.698 ms
33 <destination_ip> 24.411 ms 24.426 ms 24.323 ms
第一跳是 docker,第二跳是 AWS NAT 网关,然后穿过 AWS 网络,最终到达第 33 跳。
在运行 docker 的 EC2 主机上curl <destination_address>
运行时捕获时,我发现请求由于 ttl 而失败:tcpdump -v host <destination_ip>
ip-10-133-218-86.us-east-2.compute.internal > <destination_ip>: ICMP time exceeded in-transit, length 52
然而,检查该tcpdump
请求后发现,它在通过主机时其 TTL 为 63,表明它正确使用了 ubuntu 系统默认值 64:
Time to live: 63
我的问题是:什么原因导致 TTL 为 64 的请求在连接到目标 IP 时失败,而 traceroute 显示距离只有 33?
此时我们的选择似乎是(1)减少源和目的地之间的跳数,或者(2)增加传出请求的 TTL。
为了尝试 (2),增加 TTL,我尝试将 sys 属性更新/proc/sys/net/ipv4/ip_default_ttl=64
为/proc/sys/net/ipv4/ip_default_ttl=128
。 tcpdump 检查表明这在传出请求中得到尊重,但是调用仍然失败ICMP time exceeded in-transit
。
编辑1
tcpdump
从主机上 添加 Wireshark 屏幕截图。
编辑2
添加另一个 tcpdump,它是在卷曲同一主机但从我的本地机器上捕获的。
正如答案所指出的,[SYN,ACK] 响应的 TTL 太低,无法返回发起请求的机器。在我本地访问同一台服务器的图像中,您可以看到它比该服务器的任何其他响应少了大约 200 个跳数。
答案1
当响应到达主机时,其 TTL 仅为 1,从而阻止它们被路由到容器。