You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker容器内服务可内部访问但主机访问时浏览器及curl挂起无响应问题排查求助

Docker容器内服务可内部访问但主机访问时浏览器及curl挂起无响应问题排查求助

我在Ubuntu主机上用Docker运行了几个Web应用,每个应用监听不同端口。现在遇到一个特别头疼的问题:在Docker网络内的任意容器里,我都能正常连接并获取服务返回的数据,但从主机发起请求时,虽然能成功建立连接,却完全收不到任何数据。浏览器访问localhost:8080会一直挂起,curl也是无限等待,这到底是哪里出问题了?

端口映射与监听状态确认

先看docker ps的端口输出,显示映射是正常的:

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

netstat检查主机端口监听情况,也显示8080端口处于监听状态:

$ 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      -

主机访问的异常表现

不管是用Firefox还是Chrome访问localhost:8080,浏览器都会一直加载,没有任何响应返回。用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试过,结果也是连接上后就没有任何数据返回,一直挂着。

对比测试:主机直接运行服务正常

为了排除主机本身的网络问题,我在主机上直接启动了一个Python HTTP服务:

python3 -m http.server 8000

用curl访问这个服务完全正常,能收到响应:

$ 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">
...

我也尝试直接访问容器的IP地址(比如172.17.0.3:8080),结果还是一样,连接建立后没有响应。但反过来,在容器内部用curl访问其他容器的HTTP端点,却完全正常。

Docker Compose相关配置(docker inspect截取内容)

我是用Docker Compose部署的,docker inspect返回的部分配置如下:

"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
}
}
}

问题总结

现在情况就是:

  • 容器内部可以正常访问所有服务的HTTP端点
  • 主机上直接运行的服务可以正常被访问
  • Docker端口映射显示正常,主机端口也处于监听状态
  • 主机访问容器服务时,连接能建立,但完全收不到响应,请求一直挂起

我怀疑是Docker桥接网络出了问题,但不知道具体该怎么排查和修复。有没有大佬能指点一下,我该怎么调整才能让主机正常访问Docker容器内的服务?

备注:内容来源于stack exchange,提问作者thayne

火山引擎 最新活动