AWS ECSで実行されている(ubuntu 18を実行している)Dockerコンテナー内から、外部のデータセンターへの接続を確立しようとしています。障害の原因となっているのは、ローカルDockerネットワークによって追加された余分なホップであると考えられるところまで問題をトラブルシューティングしました。これは、宛先IPへのカールリクエストが、Docker Host EC2インスタンスからだけでなく、宛先IPから33ホップ未満のサブネットにデプロイされたときに同じdockerコンテナー内からも正常に完了するという事実によってサポートされます。
コンテナ内から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、2番目はAWS NATゲートウェイで、その後AWSネットワークを経由して最終的にホップ33に到達します。
Dockerを実行しているEC2ホストマシンでcurl <destination_address>
を使用してキャプチャしているときにtcpdump -v Host <destination_ip>
を実行すると、ttlが原因でリクエストが失敗することがわかります。
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のリクエストが送信されると、tracerouteが示す宛先IPへの接続が失敗すると、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
で失敗します。
ホストマシンのtcpdump
からWireshark screengrabを追加します。
同じホストをカールしているときにキャプチャされた別のtcpdumpをローカルマシンから追加します。
回答が指摘するように、[SYN、ACK]応答にはTTLがあり、要求を開始したマシンに戻るには低すぎます。同じサーバーをローカルでヒットしている画像では、そのサーバーによる他のどの応答よりも約200ホップ少ないことがわかります。
ホストに到着したときにTTLが1だけであり、それらがコンテナーにルーティングされないようにするのは応答です。