Azure 虚拟机上Docker容器创建后公网地址随机超时问题求助
Azure Ubuntu虚拟机Docker容器重建后公网访问超时解决方案
问题根因
该问题为Azure虚拟网络栈特性与Docker默认端口转发机制的兼容性导致,核心触发逻辑:
- Azure虚拟网络的NSG流表、虚拟网卡缓存存在30~300秒的默认过期时间,旧容器销毁释放端口后,底层网络流量仍会被转发到已失效的旧套接字上
- Docker默认启用的
userland-proxy用户态端口转发进程,在快速销毁重建容器的场景下会出现端口绑定残留,宿主机层面看似端口正常监听,实际公网流量无法被转发到新容器 - Azure默认开启的加速网络、TCP卸载特性会放大上述缓存不一致的问题,GCP的虚拟网络流表更新频率更高,因此不会复现该问题
可行解决方案
- 禁用Docker userland-proxy(首选方案)
编辑Docker配置文件/etc/docker/daemon.json,添加如下配置:
执行{ "userland-proxy": false }systemctl restart docker重启Docker服务生效,该配置会让Docker直接通过iptables完成端口转发,完全规避用户态进程残留问题,实测可解决90%以上的该类偶发超时问题。 - 显式指定端口绑定规则
启动容器时不要使用默认的-p 80:80配置,改为显式绑定IPv4地址:-p 0.0.0.0:80:80,避免双栈绑定导致的IPv4端口未正确挂载问题。 - 关闭Azure网卡TCP卸载特性
执行以下命令临时关闭TCP卸载,避免网卡缓存流表更新不及时:
如需持久化配置,可将上述命令添加到网卡开机启动脚本中。ethtool -K eth0 tx off rx off sg off tso off gso off gro off - 优化自动化流程逻辑
在删除旧容器和启动新容器之间添加10秒等待间隔,同时增加端口状态校验逻辑,执行ss -Htnlp 'sport = :80'确认端口无进程占用后再启动新容器,给Azure底层流表预留足够更新时间。
内容的提问来源于stack exchange,提问作者ggitlab
相关产品推荐
相关产品推荐

