跳转至

Docker 网络

实际多服务应用建议创建用户自定义 bridge 网络,容器可通过服务/容器名称解析彼此。

# 创建网络并查看
docker network create app-net
docker network ls
docker network inspect app-net

# 同一网络中的容器
docker run -d --name redis --network app-net redis:7-alpine
docker run --rm --network app-net redis:7-alpine redis-cli -h redis ping

端口映射

# 仅绑定本机回环地址,避免服务直接暴露到公网
docker run -d --name admin -p 127.0.0.1:8080:80 nginx:alpine

-p 主机端口:容器端口 负责主机与容器之间的入口;同一用户自定义网络中的服务通常不需要互相发布端口。生产环境不要依赖容器 IP,应使用服务名、DNS 或反向代理。

网络模式

模式 特点 适用场景
user-defined bridge 同主机容器隔离网络和名称解析 单机应用、Compose 默认选择
default bridge 旧默认网络,能力和隔离较弱 临时测试,不建议组织正式应用
host 容器直接使用主机网络命名空间 特殊性能/端口需求,隔离更弱
none 无外部网络接口 完全离线任务
macvlan/ipvlan 容器接入物理二层/三层网络 传统网络集成,需交换机和地址规划

host 模式下 -p 没有意义,端口直接占用主机。macvlan 常出现宿主机与容器默认不能直接通信的情况,使用前先设计父接口、VLAN、IPAM 和交换机策略。

数据包路径

外部客户端
  → 主机 IP:published-port
  → Docker NAT/转发规则
  → 容器 IP:container-port
  → 应用监听地址

应用若只监听容器内 127.0.0.1,端口映射仍可能无法访问;通常应监听 0.0.0.0 或容器接口。EXPOSE 只记录镜像元数据,不会自动发布主机端口。

DNS 与服务发现

用户自定义网络提供容器名/别名解析。容器重建后 IP 可变化,调用方使用服务名:

docker network connect app-net web
docker network disconnect app-net web
docker exec web getent hosts redis

localhost 永远指当前网络命名空间。应用容器中的 localhost:5432 指应用容器自己,不是数据库容器或宿主机。

多网络隔离

proxy ── frontend ── app
app ─── backend ─── database

数据库只加入 backend,不发布主机端口;反向代理只加入 frontend。应用同时加入两个网络承担连接边界。网络分段减少误暴露,但不是身份认证和数据库权限的替代品。

排障顺序

docker inspect --format '{{json .NetworkSettings.Networks}}' app
docker network inspect app-net
docker port app
ss -lntp
iptables -t nat -S
  1. 容器是否 Running,应用是否监听正确地址与端口。
  2. 两个容器是否在同一网络,名称能否解析。
  3. 容器到目标的路由、DNS 和 TLS 是否正常。
  4. 主机发布端口是否正确绑定,是否被其他进程占用。
  5. 主机防火墙、云安全组、Docker 转发/NAT 和上游 LB 是否放行。

不要用 --network host 或关闭防火墙来掩盖原因;先确定故障发生在应用监听、容器网络、主机端口还是外部网络。

官方参考:Docker networkingPort publishing