Docker Compose 网络排障:用服务名连接容器,别依赖容器 IP
【摘要】 通过一个 API 与 Redis 的 Compose 示例,说明容器如何用服务名通信,并按状态、日志、DNS、网络、端口和就绪时序逐步排查连接问题。
在本机运行多容器应用时,API 容器连接 Redis 失败,是很常见的 Compose 问题。很多时候,服务本身没坏,错在把“宿主机地址”和“容器网络地址”混在了一起。
先记住三条规则
- 容器里的
localhost指向当前容器自己,不是宿主机,也不是另一个服务。 - 同一 Compose 网络中的容器通常可以用服务名互相访问,例如 API 访问 Redis 时使用
cache:6379。 - 容器 IP 由网络分配,重建后可能变化;配置里应写服务名或网络别名,不要把 IP 写死。
一个最小的 Compose 示例
下面让 API 等待缓存服务通过健康检查,再启动应用。健康检查用于判断 Redis 是否可响应,单纯启动容器并不代表服务已经就绪。
services:
api:
build: .
environment:
REDIS_HOST: cache
REDIS_PORT: "6379"
depends_on:
cache:
condition: service_healthy
cache:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
应用配置读取服务名即可,例如 Python 中从 REDIS_HOST 读取主机名,并将端口转成整数。生产环境还应设置连接超时和有限次数的重试,避免依赖服务短暂不可用时无限等待。
按顺序排查连接失败
- 确认容器都在运行:
docker compose ps查看 API 和缓存容器的状态。 - 查看两端日志:
docker compose logs api cache区分 DNS 解析失败、连接拒绝和应用配置错误。 - 检查服务名解析:在 API 容器内查询
cache是否能解析;若解析失败,确认两项服务是否加入同一个 Compose 网络。 - 检查目标端口:Redis 默认在容器网络内监听 6379。API 连接服务时使用容器端口,不要把宿主机映射端口误当成服务间端口。
- 确认就绪时序:如果日志显示启动时连接被拒绝,加入健康检查与有上限的重试;仅写
depends_on通常只表达启动顺序,不足以保证服务已经可用。
容器间通信和宿主机访问是两回事
ports 用来把容器端口发布到宿主机,方便浏览器或宿主机程序访问。Compose 网络里的 API 访问 Redis,不需要为了容器互通而公开 Redis 端口。少暴露一个端口,也能减少不必要的访问面。
另一个常见陷阱是多个 Compose 项目默认使用彼此隔离的网络。服务名只在共同网络中可解析;如果确实需要跨项目通信,应明确创建并配置共享网络,而不是复制某次运行得到的容器 IP。
小结
容器间连接优先使用 Compose 服务名和容器端口;宿主机访问才考虑端口映射。出现故障时按运行状态、日志、名称解析、网络归属、端口和服务就绪顺序检查,通常很快能定位问题。部署到生产环境时,密码等敏感值应通过合适的密钥管理方式提供,不要写进公开仓库。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)