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
端口映射¶
-p 主机端口:容器端口 负责主机与容器之间的入口;同一用户自定义网络中的服务通常不需要互相发布端口。生产环境不要依赖容器 IP,应使用服务名、DNS 或反向代理。
网络模式¶
| 模式 | 特点 | 适用场景 |
|---|---|---|
| user-defined bridge | 同主机容器隔离网络和名称解析 | 单机应用、Compose 默认选择 |
| default bridge | 旧默认网络,能力和隔离较弱 | 临时测试,不建议组织正式应用 |
| host | 容器直接使用主机网络命名空间 | 特殊性能/端口需求,隔离更弱 |
| none | 无外部网络接口 | 完全离线任务 |
| macvlan/ipvlan | 容器接入物理二层/三层网络 | 传统网络集成,需交换机和地址规划 |
host 模式下 -p 没有意义,端口直接占用主机。macvlan 常出现宿主机与容器默认不能直接通信的情况,使用前先设计父接口、VLAN、IPAM 和交换机策略。
数据包路径¶
应用若只监听容器内 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 指应用容器自己,不是数据库容器或宿主机。
多网络隔离¶
数据库只加入 backend,不发布主机端口;反向代理只加入 frontend。应用同时加入两个网络承担连接边界。网络分段减少误暴露,但不是身份认证和数据库权限的替代品。
排障顺序¶
docker inspect --format '{{json .NetworkSettings.Networks}}' app
docker network inspect app-net
docker port app
ss -lntp
iptables -t nat -S
- 容器是否 Running,应用是否监听正确地址与端口。
- 两个容器是否在同一网络,名称能否解析。
- 容器到目标的路由、DNS 和 TLS 是否正常。
- 主机发布端口是否正确绑定,是否被其他进程占用。
- 主机防火墙、云安全组、Docker 转发/NAT 和上游 LB 是否放行。
不要用 --network host 或关闭防火墙来掩盖原因;先确定故障发生在应用监听、容器网络、主机端口还是外部网络。