Docker 网络原理
下面这份是从 Linux 网络底层 -> Docker 网络模型 -> 数据包路径 -> 访问场景 -> 常见坑的 《Docker 网络原理全景解析》。
不是“怎么用”,而是为什么这样设计、数据包怎么走。
Docker 网络本质是:Linux Network Namespace + veth + bridge + iptables NAT
-
每个容器有独立网络栈
-
包括:
- 网卡
- IP
- 路由表
- 防火墙规则
📌 容器 ≠ 进程共享网络(除非 host)
container eth0 <====> vethxxxx (host)
- 成对出现
- 一端进容器,一端在宿主机
📌 veth 就是“网线”
container
│
veth
│
docker0 (bridge)
│
宿主机网卡
- docker0 是二层交换机
- 容器 IP 在同一子网
- SNAT:容器访问外网
- DNAT:外部访问容器
📌 这是访问控制的核心
[container] --veth--> [docker0] --NAT--> [eth0] --> Internet
docker inspect container | grep IPAddress
172.17.0.2
docker run -p 8080:80 nginx
Client
↓
宿主机 8080
↓ (DNAT)
容器 80
iptables 规则本质是:
PREROUTING: 8080 -> 172.17.0.2:80
📌 容器无需感知外部端口
- 外部无法访问
- 容器只在内部网络可见
curl www.baidu.com
container 172.17.0.2
↓
docker0
↓ (SNAT)
宿主机 IP
↓
Internet
iptables 做了:
POSTROUTING: 172.17.0.0/16 -> 宿主机 IP
📌 所以外部只看到宿主机 IP
services:
api:
db:
访问方式:
api -> db:5432
- 📌 Docker 内置 DNS
- 📌 不要用 IP
- 默认不通
- 可手动 connect
docker network connect net1 container
-
NAT
-
有 IP
-
最常用
-
✅ 开发 / 测试
-
❌ 高性能数据库(慎用)
network_mode: host
特点:
- 无隔离
- 无 NAT
- 无端口映射
📌 容器端口 = 宿主机端口
- ✅ 高性能服务
- ❌ 端口冲突
-
无网卡
-
无网络
-
✅ 安全测试
-
✅ 离线任务
-
VXLAN
-
Swarm / K8S
-
❌ 性能下降
-
✅ 跨主机通信
127.0.0.11
- service name -> 容器 IP
- 同网络可见
📌 DNS 不是 /etc/hosts
--add-host=host.docker.internal:host-gateway
container -> host.docker.internal
- 使用端口映射
- 或直接访问容器 IP(仅本机)
- NAT 转发
- 路由允许即可
| 表 | 用途 |
|---|---|
| nat | DNAT / SNAT |
| filter | 防火墙 |
| mangle | 改包 |
| raw | 连接追踪 |
Docker 主要使用:
- nat
- filter
- ❌ 忘记 -p
- ❌ 服务只监听 127.0.0.1
- ❌ 用 IP 通信
- ❌ overlay 性能期望过高
- ❌ 容器 DNS 被覆盖
Docker 网络基于 Linux Namespace 隔离,每个容器有独立网络栈,通过 veth 连接到宿主机的 bridge。外部访问通过 DNAT 端口映射,容器访问外部通过 SNAT。容器间通信依赖内置 DNS。
veth 是网线
bridge 是交换机
iptables 是路由器 + 防火墙