Docker中运行Locust遇OSError: [Errno 97]地址族不支持协议问题
Docker中Locust绑定0.0.0.0出现Errno 97错误的排查
问题背景
在Docker 23.0.3中运行Locust 2.15.1时,当WebUI绑定0.0.0.0:8089时触发地址族不支持的错误,但Nginx容器绑定0.0.0.0:80可正常运行。容器内执行ip r l显示路由状态:
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
错误日志
[2023-04-08 02:12:15,725] 044913c8d54a/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces) [2023-04-08 02:12:15,742] 044913c8d54a/INFO/locust.main: Starting Locust 2.15.1 Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/opt/venv/lib/python3.10/site-packages/locust/web.py", line 478, in start_server self.server.serve_forever() File "/opt/venv/lib/python3.10/site-packages/gevent/baseserver.py", line 398, in serve_forever self.start() File "/opt/venv/lib/python3.10/site-packages/gevent/baseserver.py", line 336, in start self.init_socket() File "/opt/venv/lib/python3.10/site-packages/gevent/pywsgi.py", line 1545, in init_socket StreamServer.init_socket(self) File "/opt/venv/lib/python3.10/site-packages/gevent/server.py", line 180, in init_socket self.socket = self.get_listener(self.address, self.backlog, self.family) File "/opt/venv/lib/python3.10/site-packages/gevent/server.py", line 192, in get_listener return _tcp_listener(address, backlog=backlog, reuse_addr=cls.reuse_addr, family=family) File "/opt/venv/lib/python3.10/site-packages/gevent/server.py", line 284, in _tcp_listener sock = GeventSocket(family=family) File "/opt/venv/lib/python3.10/site-packages/gevent/_socket3.py", line 133, in __init__ self._sock = self._gevent_sock_class(family, type, proto, fileno) OSError: [Errno 97] Address family not supported by protocol 2023-04-08T02:12:15Z <Greenlet at 0x7fd349243c40: <bound method WebUI.start_server of <locust.web.WebUI object at 0x7fd34915e410>>> failed with OSError
问题分析
这个错误的核心原因是Locust依赖的gevent库在处理0.0.0.0时,默认尝试同时创建IPv4和IPv6套接字,但容器环境未启用或支持IPv6,导致IPv6套接字创建失败抛出Errno 97。
Nginx容器能正常运行是因为其默认仅监听IPv4,或对地址族的处理逻辑与gevent不同,不会强制尝试IPv6监听。而docker0网桥的linkdown状态可能加剧了网络栈异常,但不是直接触发错误的原因。
解决方法
强制Locust仅监听IPv4:启动Locust时添加环境变量禁用IPv6支持,或显式指定监听配置:
# 容器内启动命令 GEVENT_SUPPORT_IPV6=0 locust -f your_locustfile.py --web-host=0.0.0.0 --web-port=8089或在Docker run命令中注入环境变量:
docker run -e GEVENT_SUPPORT_IPV6=0 -p 8089:8089 your-locust-image禁用容器IPv6:创建容器时通过sysctl参数强制关闭IPv6:
docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 -p 8089:8089 your-locust-image修复Docker网桥状态:重启Docker服务恢复docker0网桥的正常状态:
systemctl restart docker之后重新创建Locust容器。
结论
该问题并非Docker本身或Locust核心功能的问题,而是gevent库与容器网络环境的兼容性问题,通过限制IPv4监听或调整容器网络配置即可解决。
内容的提问来源于stack exchange,提问作者Vivek Raut
相关产品推荐
相关产品推荐

