Docker容器无法连接到一个特定的外部IP,但主机可以

Pau*_*xon 7 tcpip docker

这是一个谜题,我希望通过写一个 StackOverflow 问题,我能获得一些新的见解。

简而言之,我试图弄清楚为什么我可以从主机访问https://sts.nih.gov ,但​​当其他站点工作正常时却不能从同一主机上的 docker 容器访问

我如何重现该问题...

我有一台基于云的机器(Digital Ocean),它可以愉快地建立一个 https 连接sts.nih.gov

# from host machine
curl -vv -o /tmp/test https://sts.nih.gov
Run Code Online (Sandbox Code Playgroud)

如果我在新的 docker 容器上获得 shell,我将无法访问该站点

 # get a shell within a container 
 docker run -ti ubuntu:18.04 /bin/bash

 # attempt same request...
 curl -vv --ipv4 -o /tmp/test https://sts.nih.gov
* Rebuilt URL to: https://sts.nih.gov/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 128.231.243.251...
* TCP_NODELAY set
  0     0    0     0    0     0      0      0 --:--:--  0:00:31 --:--:--     0* connect to 128.231.243.251 port 443 failed: Connection timed out
* Failed to connect to sts.nih.gov port 443: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to sts.nih.gov port 443: Connection timed out
Run Code Online (Sandbox Code Playgroud)

现在一件有趣的事情是,如果没有该--ipv4标志,该命令会尝试使用 ipv6 并且失败。

所有对外部主机的访问都会发生这种情况吗?

curl -o /tmp/test https://serverfault.com/不,例如,在 docker 容器内,工作得很好。

是DNS问题吗?

不,nslookup 能够解析容器内的地址

nslookup sts.nih.gov
Server:     67.207.67.3
Address:    67.207.67.3#53

Non-authoritative answer:
sts.nih.gov canonical name = sts.ha.nih.gov.
Name:   sts.ha.nih.gov
Address: 128.231.243.251
Name:   sts.ha.nih.gov
Address: 2607:f220:404:9124:128:231:243:251
Run Code Online (Sandbox Code Playgroud)

我也可以尝试在请求中使用 IP 地址

curl -vv -o /tmp/test https://128.231.243.251
Run Code Online (Sandbox Code Playgroud)

同样的结果——超时。

是专门针对 https 的吗?

不,这似乎是 TCP/IP 问题而不是 https 协议问题。仅使用 netcat 检查连接失败。

netcat -zvn 128.231.243.251 443
(UNKNOWN) [128.231.243.251] 443 (?) : Connection timed out
Run Code Online (Sandbox Code Playgroud)

是路由问题吗?

似乎并非如此——毕竟宿主机可以访问问题站点,docker容器也可以访问其他外部站点。

Traceroute 显示 ICMP 数据包至少正在到达目标网络

traceroute 128.231.243.251
traceroute to 128.231.243.251 (128.231.243.251), 30 hops max, 60 byte packets
 1  172.17.0.1 (172.17.0.1)  0.063 ms  0.029 ms  0.023 ms
 2  * * *
 3  10.80.5.46 (10.80.5.46)  1.758 ms 10.80.5.48 (10.80.5.48)  1.864 ms 10.80.5.38 (10.80.5.38)  4.499 ms
 4  138.197.249.112 (138.197.249.112)  1.991 ms 138.197.249.122 (138.197.249.122)  2.179 ms 138.197.249.104 (138.197.249.104)  1.961 ms
 5  138.197.251.136 (138.197.251.136)  1.659 ms 138.197.251.142 (138.197.251.142)  1.846 ms 138.197.251.138 (138.197.251.138)  1.799 ms
 6  212.187.195.149 (212.187.195.149)  4.005 ms 212.187.195.85 (212.187.195.85)  1.800 ms  1.743 ms
 7  * * *
 8  4.16.68.166 (4.16.68.166)  76.945 ms  76.901 ms  76.869 ms
 9  bth-tic-core-rt-a-te-0-0-0-0.net.nih.gov (156.40.93.1)  77.783 ms  77.754 ms  77.632 ms
10  156.40.93.170 (156.40.93.170)  76.519 ms  76.473 ms  76.429 ms
11  156.40.93.171 (156.40.93.171)  77.745 ms  76.627 ms  77.020 ms
12  * * *
...
30  * * *
Run Code Online (Sandbox Code Playgroud)

我还可以使用 TCP SYN 包显示良好的跟踪

traceroute --tcp 128.231.243.251
traceroute to 128.231.243.251 (128.231.243.251), 30 hops max, 60 byte packets
 1  172.17.0.1 (172.17.0.1)  0.066 ms  0.017 ms  0.017 ms
 2  * * *
 3  10.80.5.34 (10.80.5.34)  1.881 ms 10.80.5.46 (10.80.5.46)  2.113 ms 10.80.5.36 (10.80.5.36)  1.832 ms
 4  138.197.249.98 (138.197.249.98)  3.127 ms 138.197.249.120 (138.197.249.120)  1.978 ms 138.197.249.106 (138.197.249.106)  1.853 ms
 5  138.197.251.140 (138.197.251.140)  1.784 ms  1.826 ms 138.197.251.132 (138.197.251.132)  1.705 ms
 6  212.187.195.149 (212.187.195.149)  2.859 ms  1.457 ms  1.389 ms
 7  * * *
 8  4.16.68.166 (4.16.68.166)  76.470 ms  76.446 ms  76.520 ms
 9  bth-tic-core-rt-a-te-0-0-0-0.net.nih.gov (156.40.93.1)  77.602 ms  77.582 ms  77.492 ms
10  156.40.93.170 (156.40.93.170)  76.005 ms  76.733 ms  76.459 ms
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  128.231.243.251 (128.231.243.251)  77.268 ms  77.215 ms  76.815 ms
Run Code Online (Sandbox Code Playgroud)

下一步行动?

此时,我对如何进一步缩小范围感到困惑。对我来说,感觉远程端的网络有些不寻常,但只在 docker 的网络机制中体现出来

小智 1

您需要创建一个新的桥接 docker 网络并将容器附加到该网络。您应该能够通过这种方式连接。如果不能是因为某些 docker 服务损坏,只需重新启动 docker 即可。我也有这个问题。