Docker 容器间如何通信?
多个容器需要互相访问,比如应用容器访问数据库容器,不知道怎么配置网络
解决方案
使用自定义 Bridge 网络(推荐) 推荐
# 创建自定义网络 docker network create app-net # 启动容器时加入网络 docker run -d --name db --network app-net postgres:15 docker run -d --name web --network app-net -p 8080:80 myapp # 在 web 容器中可以直接用容器名访问 db # 连接字符串:postgresql://user:pass@db:5432/mydb
自定义 bridge 网络提供内置 DNS 解析,容器可以通过容器名互相访问。这是最推荐的容器间通信方式。
适用场景:同一主机上的多个容器需要互相通信
使用 Docker Compose(多服务推荐) 推荐
# compose.yml
services:
web:
build: .
ports:
- "8080:80"
depends_on:
- db
- redis
environment:
- DB_HOST=db
- REDIS_HOST=redis
db:
image: postgres:15
environment:
- POSTGRES_PASSWORD=secret
redis:
image: redis:7-alpine
# Compose 自动创建网络,服务名即为主机名Docker Compose 自动为所有服务创建一个共享网络,服务之间可以用服务名(service name)作为主机名互相访问。
适用场景:多个服务组成的应用,开发和部署环境
使用 host 网络模式
# 容器直接使用宿主机网络 docker run -d --network host nginx # 容器中的服务直接监听宿主机端口 # 不需要 -p 端口映射
容器直接使用宿主机的网络栈,没有网络隔离。性能最好但安全性较低,端口可能冲突。
适用场景:对网络性能要求极高,或需要访问宿主机网络服务
跨主机通信(Overlay 网络)
# 初始化 Swarm(需要多节点) docker swarm init # 创建 overlay 网络 docker network create --driver overlay my-overlay # 服务加入 overlay 网络后可跨主机通信
Overlay 网络用于 Docker Swarm 或多主机场景,容器可以跨物理机通信。生产环境多用 Kubernetes 替代。
适用场景:容器分布在多台主机上需要互相通信
注意事项
默认 bridge 网络不支持 DNS 解析,必须用 --link(已废弃)或自定义网络
host 模式在 Mac/Windows 的 Docker Desktop 上行为不同
容器间通信用容器名而非 IP,因为 IP 可能变化