当前位置:首页 > 文章列表 > 科技周边 > 业界新闻 > Docker Compose 网络文档更新,服务发现实践有哪些共识

Docker Compose 网络文档更新,服务发现实践有哪些共识

来源:17golang原创 2026-10-08 17:21:34 0浏览 收藏

Docker Compose 网络配置看起来不复杂,但团队里最常见的故障仍然集中在四件事:把容器 IP 当成固定地址、把主机端口当成容器间端口、让不该互通的服务共享网络,以及容器重建后继续重试旧连接。

当前官方文档给出的方向很明确:Compose 默认网络已经提供服务名发现;容器重建后 IP 可以变化,但服务名保持稳定;容器间通信使用容器端口;需要隔离时再显式拆分网络。

Docker Compose 网络官方文档:https://docs.docker.com/compose/how-tos/networking/

先看结论:服务发现实践形成了哪些共识

  1. 用服务名,不固定容器 IP。同一 Compose 网络中的服务可通过服务名解析。
  2. 容器间使用容器端口。主机端口主要服务于宿主机或网络外部访问。
  3. 默认网络覆盖多数本地开发场景。只有在隔离、跨项目或接入既有网络时才增加自定义网络。
  4. 容器重建后重新解析并重连。旧连接会关闭,客户端不能把旧 IP 缓存成永久地址。
  5. 按证据排查。先看网络成员,再看 DNS 和端口,最后测试实时连通性。

共识一:服务名是稳定入口,容器 IP 不是

执行 docker compose up 时,Compose 通常会为项目创建一个默认网络。加入该网络的服务可以用服务名互相定位。例如应用连接数据库时,目标应写成 db:5432,而不是某个临时的 172.x.x.x 地址。

这条规则的价值在容器重建时最明显:新容器可能获得新 IP,但 db 这个服务名不变。客户端只要重新解析名称,就能找到新实例。

Compose 默认网络服务发现与端口边界说明图

图1:Compose 默认网络中的服务名发现与端口边界说明图。

共识二:容器端口和主机端口必须分开判断

假设数据库配置为 5432:5432,同一 Compose 网络里的应用仍然应连接 db:5432。左侧主机端口用于宿主机访问,右侧容器端口用于容器网络内部通信。

如果写成 db:15432,而 15432 只是映射到宿主机的端口,容器间连接通常会失败。判断时不要只看 YAML 中有没有 ports,还要明确请求从哪里发出。

出现连接异常时,按五层顺序检查

第一层:配置是否符合预期

先确认服务名、容器端口和网络名称。若只是同一项目内的简单互通,不需要额外声明 links;默认网络已经提供基本服务名发现。

第二层:服务是否共享目标网络

两个服务只有加入同一个网络,才具备直接互通的前提。自定义网络最容易出现“配置看着都在,实际没有交集”的问题。

第三层:服务名能否被解析

从发起请求的容器内部解析目标服务名。能解析出地址,说明名称和网络成员大体正确;不能解析时,优先检查服务名拼写、网络归属和外部网络是否存在。

第四层:请求是否用了容器端口

容器内请求应指向目标容器监听的端口。只有从宿主机或网络外部访问时,才使用已发布的主机端口。

第五层:实时连接是否可达

名称解析成功不等于应用正在监听。继续测试目标端口,并检查进程是否绑定到容器可达地址,而不是只绑定 127.0.0.1。

# 查看 db 的 5432 容器端口映射到哪个主机端口
docker compose port db 5432

# 确认容器是否接入目标网络
docker network inspect myapp_backend

# 从 app 容器内重新解析 db 服务名
docker compose exec app getent hosts db

# 从 app 容器内测试 db 的容器端口
docker compose exec app sh -c 'nc -vz db 5432'

用证据快速判断故障位置

观察到的证据优先判断修复动作
服务名无法解析服务不在共享网络、名称写错或外部网络不存在核对 networks、服务名与外部网络创建状态
能解析但连接被拒绝端口写错或目标进程未监听改用容器端口,检查应用监听地址
宿主机可访问,容器间不可访问误用了主机端口或服务不共享网络改为服务名加容器端口,检查网络交集
更新容器后短暂断连旧连接仍指向已移除容器重新解析服务名并建立新连接
跨项目服务互相看不到项目处于不同默认网络显式接入同一个已创建的 external 网络

共识三:自定义网络表达信任边界

默认网络适合简单项目,但当代理不应直接访问数据库时,应通过网络成员关系表达边界。下面的配置让 proxy 只进入前端网络,让 db 只进入内部后端网络,而 app 作为两侧唯一桥接服务。

services:
  proxy:
    image: nginx:alpine
    # 代理只接入前端网络
    networks:
      - frontend

  app:
    image: example/app:latest
    environment:
      # 数据库地址使用服务名和容器端口
      DATABASE_URL: postgres://app:secret@db:5432/app
    # 应用同时接入前端与后端网络
    networks:
      - frontend
      - backend

  db:
    image: postgres:18
    environment:
      POSTGRES_PASSWORD: secret
    # 数据库只暴露在内部后端网络
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    # 内部网络不提供默认外部连通性
    internal: true

Compose 前端和内部后端网络信任边界图

图2:前端网络与内部后端网络组成的最小信任边界。

internal: true 的作用是让该网络不具备默认外部连通性。需要注意,若某个服务同时加入另一个可出站网络,它仍然可能通过另一个网络访问外部。因此隔离效果取决于服务加入的全部网络,不能只看单个网络定义。

共识四:容器重建后应重新解析并重连

Compose 更新服务时,旧容器会被移除,新容器以同一个服务名加入网络,但 IP 可能变化。指向旧容器的已打开连接会关闭;正确恢复方式是让客户端重新解析服务名并建立新连接。

这意味着连接池应具备失败淘汰、有限退避和重建连接能力。若应用把首次解析到的 IP 永久缓存,即使 Compose 网络本身正常,也会在重建后持续失败。

容器重建后的重新解析与重连关系图

图3:容器重建后的名称重解析与连接恢复关系。

跨项目发现:external 网络要克制使用

两个独立 Compose 项目默认处于不同网络。如果业务确实需要跨项目发现,可以让双方加入同一个预先创建的外部网络。Compose 不会替你创建声明为 external 的网络;网络不存在时会直接报错。

外部网络扩大了可见范围,也弱化了项目边界。团队应为它设定固定名称、创建责任、接入审批和清理策略。能通过 API、消息队列或网关解耦时,不要把共享外部网络当成默认方案。

反向验证:主动重建一次服务

修复后不要只验证“现在能连”。还应重建目标服务,确认客户端能从断连状态恢复。测试重点有三个:服务名是否仍可解析、新 IP 是否被采用、业务连接是否能在合理时间内恢复。

# 记录当前 db 服务名解析结果
docker compose exec app getent hosts db

# 强制重建 db,模拟更新后的容器替换
docker compose up -d --force-recreate db

# 再次解析服务名,确认客户端不依赖旧 IP
docker compose exec app getent hosts db

# 验证应用到数据库容器端口的连接已经恢复
docker compose exec app sh -c 'nc -vz db 5432'

发布前检查清单

  • 服务间地址是否全部使用 Compose 服务名,而不是固定容器 IP?
  • 容器内请求是否使用目标容器端口,而不是主机端口?
  • 每一对需要互通的服务是否至少共享一个网络?
  • 每一个不应直连的服务对是否通过网络成员关系隔离?
  • 内部网络上的服务是否还加入了其他可出站网络?
  • 外部网络是否已创建,并有明确的生命周期负责人?
  • 连接池是否会淘汰失效连接、重新解析服务名并重连?
  • 是否执行过一次目标服务重建后的恢复验证?

小结

Docker Compose 当前网络文档传递的核心并不是增加配置,而是减少隐式假设:把服务名作为稳定身份,把容器端口作为内部通信边界,把自定义网络作为信任边界,再把重建后的重新解析与重连当成正常运行条件。

排障时坚持“网络成员、名称解析、端口选择、实时连通、重建恢复”这条证据链,多数 Compose 服务发现问题都能在几分钟内缩小范围。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
限制协议版本与密码套件同时保留兼容性说明限制协议版本与密码套件同时保留兼容性说明
上一篇
限制协议版本与密码套件同时保留兼容性说明
证书轮换时旧长连接会立即失效吗,更新范围怎样判断
下一篇
证书轮换时旧长连接会立即失效吗,更新范围怎样判断
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    378次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    450次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    458次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    401次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    229次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码