Docker中Django连接远程MySQL出现客户端IP不一致问题
问题原因及解决办法
原因分析
你遇到的核心问题是两种连接场景下,Docker容器处于不同的Docker网络,导致远程MySQL看到的客户端IP不一致:
- 直接通过
docker exec或docker run进入shell的容器,默认使用Docker自带的bridge网络,IP段多为172.17.0.0/16,所以MySQL显示的是这个网段的IP。 - 运行Django runserver的容器(尤其是用docker-compose启动的情况),默认会使用Docker创建的自定义bridge网络,IP段通常是
192.168.x.x,因此MySQL识别的是这个网段的192.168.80.4。
同一个容器不会出现两种出口IP的情况,所以大概率是你在两种场景下用了不同的容器实例,分别归属不同的Docker网络。
解决办法
要让两种连接方式使用相同的客户端IP,只需确保两种场景的容器处于同一个Docker网络即可:
场景1:用docker-compose管理Django容器
- 先查看docker-compose创建的专属网络名称:
通常名称格式是docker network ls<你的项目名>_default。 - 进入容器时指定这个网络:
或者更简单,直接用docker-compose进入容器,默认就是项目专属网络:docker run --network=<项目名>_default -it <你的Django镜像名> bashdocker-compose exec <服务名> bash
场景2:用docker run启动Django容器
- 启动runserver时明确指定使用默认的
bridge网络,和你进shell的容器保持一致:docker run --network=bridge -p 8000:8000 <你的Django镜像名> python manage.py runserver 0.0.0.0:8000
特殊情况排查(同一容器出口IP不同)
如果确实是同一个容器出现两种出口IP,检查容器内的路由规则:
- 在shell中执行
ip route查看默认路由。 - 在Django代码中添加打印路由的逻辑:
对比两者的默认路由是否一致,若不一致,调整容器的路由规则,确保所有进程使用同一个网卡作为出口。import subprocess result = subprocess.run(['ip', 'route'], capture_output=True, text=True) print(result.stdout)
内容的提问来源于stack exchange,提问作者cutthroatbill
相关产品推荐
相关产品推荐

