避坑 12:90% 的 Docker 新手都栽过!Compose 用 --scale 扩容后,负载均衡居然完全失效
摘要: 90%的Docker新手在使用docker compose --scale扩容服务时,因Nginx未配置动态DNS解析,导致负载均衡失效,请求仍集中在旧容器。解决方案是在Nginx配置中添加resolver 127.0.0.11 valid=5s并采用变量形式的proxy_pass,确保DNS结果定期刷新。同时需避免为可扩展服务设置container_name,并配置健康检查。文末提供《D
文章目录
避坑 12:90% 的 Docker 新手都栽过!Compose 用 --scale 扩容后,负载均衡居然完全失效

熬到凌晨才发现!Compose 扩容后负载均衡居然完全不生效!
明明用 --scale 扩了实例,结果请求全打在旧容器,新容器没流量,扩容了等于没扩,服务还是被打崩?
90% 的 Docker 新手都栽过这个跟头,今天一文给你一招彻底解决,文末还免费送**《Docker 高频避坑指南 20 条》**。
坑点拆解 + 踩坑后果
这个问题的核心根源只有一个:你的 Nginx 反向代理配置,缺少了 Docker 内置 DNS 的关键配置。
Docker 内置了 DNS 服务器127.0.0.11,会自动把服务名解析到所有对应容器的 IP;
但 Nginx 默认会永久缓存 DNS 解析结果,只会在启动时解析一次服务名对应的 IP,后续扩容新增的容器 IP,Nginx 完全感知不到,依旧只把请求转发给启动时解析到的旧容器 IP,最终导致负载均衡彻底失效。
踩中这个坑的后果极其严重:不仅扩容操作完全白做,业务高峰期单容器依旧被打满,接口超时、服务宕机,最终线上业务中断,直接背锅。
现成解决方案(直接复制就能用)
不用懂复杂的 DNS 服务发现底层原理,照着下面的配置改,就能彻底解决这个问题,零思考、零修改,新手直接抄作业。
核心根治配置:Nginx 新增 DNS 解析配置
在你的 Nginx 配置文件里,加上这一行核心配置,同时调整 proxy_pass 的写法,完整可复制的配置如下:
server {
listen 80 default_server;
# 核心配置:指定Docker内置DNS服务器,每5秒刷新一次解析结果
resolver 127.0.0.11 valid=5s;
# 关闭DNS解析IPV6,避免不必要的解析报错
resolver_timeout 3s;
location / {
# 关键:不要把服务名写死在proxy_pass里,用变量方式触发动态解析
set $backend_server http://flask-demo:5000;
proxy_pass $backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 健康检查接口,生产环境必配
location /health {
access_log off;
return 200 "healthy\n";
}
}
配套 docker-compose.yml 完整配置
确保 Nginx 和业务服务在同一个网络,同时不要给业务服务设置固定 container_name,否则无法水平扩展,完整配置直接复制:
name: flask-scale-demo
services:
# 你的业务服务,这里以flask为例,可替换成你的java/go等服务
flask-demo:
build: ./app
image: flask-demo:v1.0.0
environment:
REDIS_HOST: redis-server
# 绝对不要写container_name!否则无法scale扩展
networks:
- app-network
restart: always
# 健康检查,确保服务就绪后再接入流量
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 5s
timeout: 3s
retries: 3
start_period: 10s
# Nginx反向代理服务
nginx:
image: nginx:stable-alpine
ports:
- "8080:80"
volumes:
# 挂载上面修改好的nginx配置文件
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- app-network
restart: always
depends_on:
flask-demo:
condition: service_healthy
# 依赖的中间件服务,按需保留
redis-server:
image: redis:7.2.4
networks:
- app-network
volumes:
- redis-data:/data
restart: always
# 统一网络,确保服务间可通信
networks:
app-network:
driver: bridge
# 数据卷,持久化中间件数据
volumes:
redis-data:
一键水平扩展命令
配置修改完成后,先启动服务,再执行这条命令,即可一键扩展实例数,把末尾的数字改成你想要的实例数量即可:
# 1. 先启动基础服务
docker compose up -d --build
# 2. 一键把flask-demo服务扩展到3个实例
docker compose up --scale flask-demo=3 -d
负载均衡生效验证方法
执行下面的命令,多次访问接口,看返回的容器 ID 是否变化,变化就代表负载均衡已生效:
# 多次执行,查看返回的容器主机名(即容器ID)
curl http://localhost:8080
额外避坑要点
- 绝对不要给需要水平扩展的服务设置
container_name,Docker 不允许重名容器,会直接导致 scale 扩展失败 - proxy_pass 必须用变量方式写,不能直接写
proxy_pass http://flask-demo:5000;,否则 Nginx 依旧会永久缓存解析结果 - 生产环境建议给业务服务配置健康检查,避免把请求转发给未就绪的容器
以上就是这个问题的全场景解决方案,照着做就能解决 99% 的问题,不用再到处翻教程踩坑。
写在最后
今天内容就到这里,大家有问题可以在评论区留言。
如果,你不想再踩这类 90% 的新手坑,想要系统搞定 Docker 全流程操作,我刚上线了22节**《Docker 从0到1入门实战》**体系化专栏。
一节一个主题,配套可直接复用的代码模板、全场景避坑指南,还有专属社群答疑,帮你少走 90% 的自学弯路。
公众号专属早鸟价,前 100 名仅 50 元,不到一顿饭钱,就能搞定职场必备的Docker技能,点击文末**【阅读原文】**即可了解详情。
新手专属福利
为了帮大家更快上手 Docker,我给大家整理了专属资料,都是我自己生产环境在用、新手能直接抄的实战内容:
- 《Docker 高频避坑指南 20 条》:新手入门最高频 20 个坑的完整避坑方案,照着做避开 90% 的问题
- 《Docker Compose 生产级最佳实践》:包含了生产部署核心原则、官方标准做法、避坑红线,零基础也能直接落地
- Docker官方维护**《10套开箱即用Compose配置文件》**:覆盖 Python / NGINX / MySQL等主流技术栈,可直接复制到生产环境使用
2 种资料领取方式:
👉 方式一(极速领取):前往我的「主页」,点击「领资料」->「联系我」,加我好友,自动发放 “资料链接” + 全套福利
👉 方式二(便捷领取):私信我,发送关键词【Compose】,自动给你资料领取详情。
关注我的账号,我会持续更新 Docker、云原生、Python 后端的实战干货,把我踩过的坑、总结的实战经验全部分享给你,帮你从入门到精通,少走弯路。
我们下期再见。
其他疑问
避坑 11:线上崩了才发现!用 latest 标签根本无法回滚,90% Docker 新手都踩过这个致命坑
避坑 10:熬到凌晨才发现!Compose 改完代码更新不生效,90% 新手都踩过这个坑
避坑 9:凌晨 2 点线上翻车!就因为用了 down && up 更新 Compose 服务,90% 新手都踩过
避坑 8:熬到凌晨才发现!Docker Compose 改完配置不生效,居然是 restart 用错了
避坑 7:90% Docker 新手都栽过的隐蔽坑!端口映射配置全对,服务就是访问不到?一文讲透根源
相关内容我都给大家做好了,感兴趣的朋友来「我的主页」找一找,直接就可以看到。
欢迎关注 「王二哥的技术笔记」,每天分享「Docker」、「Python」、「FastAPI」、「Flask」有趣干货,千万不要错过!
更多推荐


所有评论(0)