使用docker-compose时,如何通过主机名ping通Docker网络中的其他容器?
解决Docker Compose容器无法通过主机名/服务名互相ping通的问题
我来帮你搞定这个容器间通信的问题——你遇到的核心问题是默认的Docker bridge网络不支持容器名/服务名的自动DNS解析,而你刚好在配置里指定了用这个默认网络,所以只能靠IP通信。
先复盘下你的场景:
你的docker-compose配置是这样的:
version: "3" services: main: image: python:3.5.2 entrypoint: /usr/bin/yes network_mode: bridge another: image: python:3.5.2 entrypoint: /usr/bin/yes network_mode: bridge
启动容器后,不管你尝试用服务名main、容器全名dockerplayground_main_1还是容器ID,都没法ping通,只有直接用容器的IP地址才能成功通信。
为啥会这样?
Docker里有两种bridge网络,区别很大:
- 默认bridge网络:就是你配置里指定的
network_mode: bridge,这是Docker安装时自带的网络。它没有内置DNS服务,容器之间只能通过IP互相访问,或者用老旧的links配置来做名称映射。 - 自定义bridge网络:Docker Compose默认会给每个项目创建一个专属的自定义bridge网络(比如你的项目叫
dockerplayground,就会生成dockerplayground_default网络)。这种网络自带DNS解析功能,容器可以直接通过服务名、容器名互相访问,不需要记IP。
你手动指定了network_mode: bridge,等于强制容器放弃了Compose默认的自定义网络,自然就没法用名称解析了。
怎么解决?
方案1:移除network_mode: bridge(强烈推荐)
这是最简单也最符合Docker Compose最佳实践的方法,只需要删掉配置里的network_mode: bridge就行:
version: "3" services: main: image: python:3.5.2 entrypoint: /usr/bin/yes another: image: python:3.5.2 entrypoint: /usr/bin/yes
然后重启容器:
docker-compose down docker-compose up -d
现在再去测试,比如在another容器里pingmain服务:
docker exec -it dockerplayground_another_1 ping main
应该能直接ping通了——自定义网络会自动把服务名映射到对应容器的IP,完全不用你手动配置。
方案2:如果必须用默认bridge网络(不推荐)
要是你因为特殊需求一定要用默认bridge网络,可以用links配置来实现名称解析,修改docker-compose.yml:
version: "3" services: main: image: python:3.5.2 entrypoint: /usr/bin/yes network_mode: bridge another: image: python:3.5.2 entrypoint: /usr/bin/yes network_mode: bridge links: - main
重启容器后,在another容器里就能通过main这个名称ping通对应的容器了。不过要注意,links是Docker的旧特性,官方更推荐用自定义网络来实现容器间通信,因为自定义网络的隔离性和扩展性更好。
内容的提问来源于stack exchange,提问作者Kent Shikama
相关产品推荐
相关产品推荐

