容器内Python脚本无法执行HTTP GET请求的问题求助
容器内HTTP请求被拒绝(ping正常)的排查与解决
问题现象
运行Python脚本的Docker容器内,ping目标主机(mDNS名称iot-ns-controller.local或IP)正常连通,但执行requests.get("http://iot-ns-controller.local:8081")时返回连接拒绝错误,容器外运行相同脚本完全正常;访问host.docker.internal也出现同样错误。
报错信息:
>>> requests.get("http://iot-ns-controller.local:8081") Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/urllib3/connection.py", line 174, in _new_conn conn = connection.create_connection( File "/usr/lib/python3.10/site-packages/urllib3/util/connection.py", line 95, in create_connection raise err File "/usr/lib/python3.10/site-packages/urllib3/util/connection.py", line 85, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 111] Connection refused During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen httplib_response = self._make_request( File "/usr/lib/python3.10/site-packages/urllib3/connectionpool.py", line 398, in _make_request conn.request(method, url, **httplib_request_kw) File "/usr/lib/python3.10/site-packages/urllib3/connection.py", line 239, in request super(HTTPConnection, self).request(method, url, body=body, headers=headers) File "/usr/lib/python3.10/http/client.py", line 1282, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/lib/python3.10/http/client.py", line 1328, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/lib/python3.10/http/client.py", line 1277, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib/python3.10/http/client.py", line 1037, in _send_output self.send(msg) File "/usr/lib/python3.10/http/client.py", line 975, in send self.connect() File "/usr/lib/python3.10/site-packages/urllib3/connection.py", line 205, in connect conn = self._new_conn() File "/usr/lib/python3.10/site-packages/urllib3/connection.py", line 186, in _new_conn raise NewConnectionError( urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7faa6658a0>: Failed to establish a new connection: [Errno 111] Connection refused During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/requests/adapters.py", line 489, in send resp = conn.urlopen( File "/usr/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen retries = retries.increment( File "/usr/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment raise MaxRetryError(_pool, url, error or ResponseError(cause)) urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='iot-ns-controller.local', port=8081): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7faa6658a0>: Failed to establish a new connection: [Errno 111] Connection refused')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.10/site-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) File "/usr/lib/python3.10/site-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) File "/usr/lib/python3.10/site-packages/requests/sessions.py", line 587, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3.10/site-packages/requests/sessions.py", line 701, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3.10/site-packages/requests/adapters.py", line 565, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='iot-ns-controller.local', port=8081): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7faa6658a0>: Failed to establish a new connection: [Errno 111] Connection refused'))
排查与解决步骤
1. 检查目标服务的监听地址
这是最常见的原因:目标服务只绑定了主机的127.0.0.1(本地环回),容器无法访问这个地址。
- 在主机上执行
netstat -tulpn | grep 8081(或ss -tulpn | grep 8081),查看监听地址是否为0.0.0.0:8081(允许所有网卡访问) - 如果是
127.0.0.1:8081,修改服务配置,将监听地址改为0.0.0.0,重启服务后再测试
2. 验证主机防火墙规则
防火墙可能允许ICMP(ping)但拦截了TCP 8081端口的流量:
- 临时关闭主机防火墙测试:比如
ufw disable(Ubuntu)或systemctl stop firewalld(CentOS),如果能访问,说明是防火墙问题 - 永久解决:添加规则允许容器网段访问8081端口,比如
ufw allow from 172.17.0.0/16 to any port 8081(容器默认网段一般是172.17.0.0/16,可通过docker inspect <容器ID> | grep Subnet确认)
3. 调整Docker网络配置
- host.docker.internal问题:Linux上Docker默认不自动配置这个域名,启动容器时添加参数
--add-host host.docker.internal:host-gateway,让容器能解析到主机IP - 尝试host网络模式:启动容器时用
docker run --network host ...,容器直接使用主机网络,此时再测试HTTP请求(注意避免端口冲突)
4. 确认mDNS解析的IP正确性
虽然ping能通,但mDNS可能解析到了主机的127.0.0.1:
- 在容器内执行
nslookup iot-ns-controller.local,查看解析出的IP - 直接用该IP访问测试:
requests.get("http://<解析出的IP>:8081"),如果解析的是主机外部网卡IP才能正常访问
5. 排查容器内代理设置
容器内的HTTP代理可能导致连接失败:
- 检查容器内环境变量:
echo $http_proxy $https_proxy,如果有代理设置,启动容器时清空:docker run --env http_proxy="" --env https_proxy="" ...
内容的提问来源于stack exchange,提问作者lbedogni
相关产品推荐
相关产品推荐

