Docker 网络
1. 网络对象与驱动
列出网络:
docker network ls
docker network inspect bridge常见驱动:
| 驱动 | 范围 | 用途 |
|---|---|---|
bridge | 单台 Linux Engine | 独立容器与 Compose 的默认选择 |
host | 宿主机网络命名空间 | 极少数低开销或特殊网络程序 |
none | 无普通网络接口 | 完全离线或自行配置网络 |
overlay | Swarm 多节点 | Swarm 服务跨主机通信 |
macvlan | 二层网络 | 容器像物理主机一样拥有 LAN 地址 |
ipvlan | 二/三层网络 | 大规模或特定网络拓扑 |
本文重点介绍单机 Engine 的 user-defined bridge。
2. 默认 bridge 与自定义 bridge
自定义 bridge 提供更好的 DNS、隔离和生命周期管理:
docker network create app-net
docker run -d --name db \
--network app-net \
alpine:3.23 sleep 300
docker run --rm --network app-net \
busybox nslookup db此处名为 db 的 Alpine 容器只用于 DNS 演示,不运行数据库,也无数据库初始化前置。先用 docker ps --filter name=db 核对它仍在运行;练习结束后 docker rm -f db 并在无引用时移除 app-net。各节命令是独立示例,第 3 节不要重复创建同名网络。
同一自定义网络中的容器可通过容器名或 network alias 解析。不要依赖动态容器 IP:
docker network inspect app-net \
--format '{{json .Containers}}'默认 bridge 的旧式 --link 已不适合作为服务发现方案。
3. 创建带子网的网络
docker network create \
--driver bridge \
--subnet 172.30.10.0/24 \
--gateway 172.30.10.1 \
app-net静态地址仅在明确需要时使用:
docker run -d \
--name legacy \
--network app-net \
--ip 172.30.10.20 \
legacy-app:1.0规划前核对:
ip route
docker network ls
docker network inspect NETWORK网段不能与宿主机 LAN、VPN、VPC、Kubernetes Pod/Service CIDR 冲突。
4. 连接多个网络
docker network create frontend
docker network create backend
docker run -d --name api --network frontend team-api:latest
docker network connect backend api
docker network inspect frontend
docker network inspect backend断开:
docker network disconnect frontend api连接多个网络可以分隔入口与数据层,但不自动实现应用级授权。仍需认证、TLS 和最小端口暴露。
5. Network alias
docker run -d \
--name api-blue \
--network app-net \
--network-alias api \
team-api:blue同一 alias 可对应多个容器,DNS 可能返回多个地址;这不是具备健康检查、会话保持和高级负载均衡的完整服务发现系统。
6. 端口发布
语法:
HOST_IP:HOST_PORT:CONTAINER_PORT[/PROTOCOL]示例:
# 仅宿主机可访问
docker run -d --name local-web \
-p 127.0.0.1:8080:80 \
nginx:alpine
# 所有 IPv4 地址可访问
docker run -d --name public-web \
-p 0.0.0.0:8081:80 \
nginx:alpine
# UDP
docker run -d --name dns \
-p 127.0.0.1:5353:53/udp \
dns-image:1.0省略宿主机地址通常会绑定所有地址:
docker run -p 8080:80 nginx安全警告: 这可能使服务对办公网或公网可达。优先写明
127.0.0.1,需要外部访问时由反向代理、防火墙和安全组控制。
查看映射:
docker port local-web
docker inspect local-web --format '{{json .NetworkSettings.Ports}}'
ss -lntup随机宿主机端口:
docker run -d -P --name random-web nginx:alpine
docker port random-web 80/tcp7. EXPOSE 与 publish 的区别
Dockerfile:
EXPOSE 8080EXPOSE 是镜像元数据,说明应用预期监听端口;它不会自动开放宿主机端口。真正发布需要 docker run -p 或 Compose ports。
容器间在同一网络直接使用容器端口:
http://api:8080不是宿主机发布端口。
8. 容器 DNS
自定义网络中的内置 DNS 通常在容器 /etc/resolv.conf 中体现:
docker exec api cat /etc/resolv.conf
docker exec api getent hosts db指定 DNS:
docker run --rm \
--dns 10.0.0.53 \
--dns-search example.internal \
alpine cat /etc/resolv.confdaemon 全局 DNS 配置会影响新建容器。变更前评估 split DNS、VPN 和内部域名。
9. 从容器访问宿主机
不要硬编码 bridge gateway。Linux Engine 可显式映射:
docker run --rm \
--add-host host.docker.internal:host-gateway \
curlimages/curl \
http://host.docker.internal:8080Docker Desktop 通常提供 host.docker.internal。生产中更推荐通过稳定网络端点访问宿主服务。
10. 内部网络
docker network create --internal backend-only内部网络限制外部连接路径,适合数据库或队列层。连接到多个网络的容器可能仍能转发流量,因此不要把它当作唯一安全边界。
11. Host 网络
docker run --rm --network host nginx:alpineHost 模式共享宿主网络命名空间:
- 不需要
-p,端口直接占用宿主机; - 隔离减弱;
- 端口冲突直接发生;
- 跨平台行为和支持范围不同。
仅在测量证明需要且安全评审通过时使用。
12. None 网络
docker run --rm --network none alpine ip addr通常只有 loopback。适合纯计算任务或测试网络依赖,但挂载和其他权限仍需单独限制。
13. IPv6
IPv6 需要 daemon、网络地址池、防火墙和上游路由共同配置。示例:
docker network create \
--ipv6 \
--subnet fd00:30:10::/64 \
dual-stack-net检查:
docker network inspect dual-stack-net
docker run --rm --network dual-stack-net alpine ip -6 addr不要只为容器分配 IPv6 而遗漏入口防火墙、DNS AAAA、出站路由和监控。
14. Firewall
Docker 会创建 iptables/nftables 相关规则。重要原则:
- 不要手工删除 Docker 自动维护的 chain。
- 入口控制可放在云安全组、外部防火墙和
DOCKER-USERchain。 - 发布端口可能绕过 ufw 的直观策略,应做真实连通性测试。
- Engine 29 的 nftables 后端版本状态和限制应以当前官方文档为准。
查看现场:
sudo iptables -S DOCKER-USER
sudo iptables -t nat -S DOCKER
sudo nft list ruleset命令可能因所选后端而不同,不要同时用多个工具随意改规则。
15. Macvlan/IPvlan 注意
Macvlan 可让容器直接出现在物理二层网络,但:
- 交换机端口需允许多个 MAC;
- 宿主机与 macvlan 容器默认可能不能直接通信;
- 地址必须由 IPAM 严格规划;
- 云平台可能禁止这种二层行为;
- 容器暴露面更接近真实主机。
docker network create -d macvlan \
--subnet=192.0.2.0/24 \
--gateway=192.0.2.1 \
-o parent=eth0 macvlan-net以上地址仅是文档示例网段,不可直接用于生产。
16. 网络排障流程
16.1 确认应用监听
docker exec api ss -lntup
docker logs --tail 100 api应用应监听 0.0.0.0 或容器接口,而不是只监听容器内 127.0.0.1。
16.2 确认网络连接与 DNS
docker inspect api --format '{{json .NetworkSettings.Networks}}'
docker network inspect app-net
docker exec api getent hosts db16.3 从同网络探测
docker run --rm --network app-net \
curlimages/curl -fsS http://api:8080/healthz使用临时调试容器前,确保镜像来源可信且环境允许拉取。
16.4 从宿主机探测
docker port api
curl -v http://127.0.0.1:8080/healthz
ss -lntp | grep ':8080'16.5 从外部探测
核对安全组、防火墙、反向代理、DNS 和路由。不要因本机 curl 成功就判断公网可用。
17. 常见故障
| 现象 | 常见原因 | 首查 |
|---|---|---|
| 容器名无法解析 | 不在同一自定义网络 | docker network inspect |
| Connection refused | 进程未监听或端口错误 | ss、日志 |
| Timeout | 路由、防火墙、服务卡死 | ip route、规则、stats |
| 宿主端口占用 | 其他进程/容器已监听 | ss -lntp、docker ps |
| 外部不可达、本机可达 | 绑定了 127.0.0.1 或入口策略阻断 | docker port、安全组 |
| VPN 开启后失联 | Docker 子网与 VPN 网段冲突 | 路由表、地址池 |
| DNS 间歇失败 | 上游 DNS、搜索域或 MTU | resolv.conf、daemon 日志 |
18. 删除网络
docker network rm unused-net
docker network prune警告: prune 会删除所有未被容器使用的自定义网络。先执行
docker network ls并确认自动化不会依赖预创建网络。
19. 官方参考
继续阅读
- 命令
- 命令
- 故障排查