如何用容器名实现 Docker 容器之间的互访(ping/连接)?
把容器接入同一个用户自定义网络(docker network create + docker run --network),可用 Docker 内置 DNS 解析容器名;实际连接仍需进程监听和策略允许。默认 bridge 不自动解析容器名,手工 hosts 或旧 link 另论。
核心:Docker 的内置 DNS 只在用户自定义网络上生效。创建网络 docker network create mynet,容器启动时 --network mynet --name api 加入,同网络的其他容器就能直接用 ping api、curl http://api:8080 访问它,无需查 IP。默认bridge不提供同样的自动名称解析;旧link或手工hosts仍可能提供名称,但不推荐依赖。
完整步骤
# 1. 创建自定义网络
docker network create mynet
# 2. 容器启动时加入(显式--name便于获得稳定名称,但不是语法必需)
docker run -d --name web --network mynet nginx
docker run -d --name api --network mynet myapi
# 3. 互访验证
docker run --rm --network mynet curlimages/curl:8.12.1 -fsS http://api:8080/health # 独立客户端,不假定nginx镜像有curl/ping
运行中的容器也能补接入:
docker network connect mynet existing-container
compose 项目天然自带
同一 compose 文件的服务默认接入项目自建网络,直接用服务名互访:
services:
web:
image: nginx
api:
build: .
web 里 curl http://api:3000 即可,连 ports 映射都不用给 api 配(内部端口直接可达)。
注意事项
- 名称解析的是容器名/服务名/网络别名,未指定--name也会生成名称,可显式命名提高可预测性;还可用
--network-alias加别名 - 老
--link已废弃,不要再学 - 跨 compose 项目互访:把一方接入另一方的网络,或建一个外部共享网络(
external: true) - ping 只是连通性验证,实际应用走 TCP 连接——
nc -zv api 8080更贴近真实
常见问题(FAQ)
Q:默认 bridge 上真的不能按名字访问吗?
A:默认bridge不提供同样的自动容器名解析,手工hosts或旧link是例外——这也是自定义网络被广泛推荐的原因之一。
Q:一个容器能同时进多个网络吗?
A:可以,docker network connect 接多个,常用于前后端分层隔离。
Q:ping 通但连不上端口?
A:DNS/ICMP成功不证明TCP服务可用,查对端容器内应用是否监听该端口:docker exec api ss -ltn。