docker 網路:連接到本機上的伺服器時瀏覽器和curl 掛起

docker 網路:連接到本機上的伺服器時瀏覽器和curl 掛起

我有幾個 Web 應用程式在 ubuntu 主機上的 docker 中運行。每個應用程式都在不同的連接埠上偵聽。當在 docker 網路中的任何容器內時,我可以連接並從服務接收數據,但是,當從主機運行請求時,我可以成功連接,但沒有接收到數據。當我從容器外部連接到服務時,為什麼服務不回傳任何資料?

當我運行時,Docker 在“PORTS”下報告了這一點docker ps

0.0.0.0:8080->8080/tcp, :::8080->8080/tcp

netstat 報告伺服器正在偵聽該連接埠:

$ netstat -anp | grep 8080
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      -                                      
tcp6       0      0 :::8080                 :::*                    LISTEN      -

但是,當我在瀏覽器中訪問 localhost:8080 時(我嘗試了 Firefox 和 chrome),瀏覽器掛起,就好像已連接一樣,但沒有發送任何資料。同樣,curl 永遠掛起:

$ curl -vvv localhost:8080
* Uses proxy env variable no_proxy == 'localhost,127.0.0.1,::1'
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
^C

我也嘗試使用 telnet 連接到它,結果類似。我嘗試直接在主機上運行快速 http 伺服器,它工作正常:

python3 -m http.server 8000
$ curl -vvv localhost:8000
* Uses proxy env variable no_proxy == 'localhost,127.0.0.0/8,::1'
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.8.13
< Date: Fri, 09 Dec 2022 12:36:03 GMT
< Content-type: text/html; charset=utf-8
< Content-Length: 16768
< 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
...

我還嘗試連接到 docker 容器 ip: (172.17.0.3:8080) ,結果相同。

但是,當我嘗試在其中一個容器內執行curl 時,我能夠存取任何容器中的http 端點。

所有這些讓我相信我的主機上的 docker 網路(docker 橋?)有問題。

我正在使用 docker 撰寫。 Docker 檢查報告以下內容(部分):

"HostConfig": {
            "Binds": [],
...
            "NetworkMode": "docker-compose-example_default",
            "PortBindings": {
                "8080/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8080"
                    }
                ]
            },
...
"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "1b53a5b6580187b714c6d7d0c9f81a015d585cd0bb0d62da579a4fe7514d47ea",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "8080/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8080"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8080"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/1b53a5b65801",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "docker-compose-example_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "dc0813038a3b",
                        "adminer"
                    ],
                    "NetworkID": "65c6700f5445a6ce0f98a0a4e14e3e10577f40706411f639a4f9da5b1cfdd52e",
                    "EndpointID": "0f42ae8ce893fb4f33168c31df0d5de38d2e8ca67521802ba76589a8a0cb1bea",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }
        }

回顧:我可以連接到容器內的這些服務,但無法從主機連接到它們,即使根據所有報告,伺服器正在偵聽連線。

我需要做什麼才能從主機連接到 docker 內運行的服務?

答案1

我找到了解決方法,但不是解決方案。我發現僅當我連接到 VPN 時此問題仍然存在。顯然,這是一個常見的抱怨。斷開連線時,連線按預期工作。

解決方法是關閉 VPN 並重新啟動 docker 容器。 FWIW,這並不總是有效,特別是如果我在打開 VPN 的情況下運行,然後在關閉 VPN 後再次嘗試。在這種情況下,我發現更改 docker-compose 網路中的 CIDR 可以讓我的工作正常進行。希望這可以幫助任何遇到相同問題的人。

對於如何在打開 VPN 的情況下工作尚無定論,到目前為止,還沒有任何方法(包括創建“墓碑”docker 橋)對我有用。

相關內容