Docker 容器跨主机相互访问
1 问题
默认情况下,容器连接在所有启用的主机 Docker 网络的默认 bridge 网络桥上,容器之间通过内部 IP(如 172.17.x.x)互通,但这一 IP 仅在本机有效。当两台主机上的容器需要直接通信时,就需要「跨主机」网络方案。
2 方案概览
| 方案 | 适用场景 | 说明 |
|---|---|---|
| host 端口映射 | 少量服务 | 通过 -p 宿主机端口:容器端口 暴露,最简单 |
| Swarm/overlay 网络 | 多机编排 | Docker Swarm 或使用 docker network create -d overlay |
| 第三方插件网络 | 复杂网络策略 | Weave、Calico、Flannel 等 |
3 方法一:host 网络 + 端口映射
把容器的服务端口映射到宿主机端口,其他主机直接访问 宿主机IP:端口 即可。
docker run -dit -p 8080:80 --name web nginx
# 主机A 访问主机B的容器
curl http://hostB_IP:8080
优点:零额外组件;缺点:需要维护端口规划,缺少 DIP 直连能力。
4 方法二:overlay 网络
基于 VXLAN 封装的 overlay 网络让不同主机的容器处于同一虚拟子网,可以直接用容器 IP 互访。
配置(同一 Swarm 集群内):
# 初始化 swarm(仅需在 manager 节点执行一次)
docker swarm init --advertise-addr <本机IP>
# 创建 overlay 网络
docker network create -d overlay --attachable my-overlay
# 其他主机以 worker 身份加入(第3步中 manager 输出的命令)
docker swarm join --token <token> <manager-IP>:2377
# 两个主机的容器都连接到该网络
docker run -dit --network my-overlay --name appA ...
docker run -dit --network my-overlay --name appB ...
之后 appA 可直接通过服务名 appB 或 overlay 内 IP 访问 appB。
5 跨主机容器相互访问要点
- 容器使用不同主机的同一 overlay 网络时,保证节点间 4789/UDP(VXLAN)与 7946/TCP、UDP(swarm)端口连通,并开启 Linux 内核
iptables/ip_forward。 - 关闭
iptables曾导致跨主机容器无法互连,检查:
sysctl net.ipv4.ip_forward # 需要为 1
echo 1 > /proc/sys/net/ipv4/ip_forward
- 若容器需要从外部网络感知固定 IP,可在 compose 或 run 时指定:
--ip 192.0.2.10
6 总结
- 少量容器、简单拓扑:使用 host 端口映射;
- 成规模的多机部署、需要服务发现:使用 overlay 网络(配合 Docker Swarm 或 Kubernetes)。
阅读 —
·
全站 —