🧱 1. Docker 默认会创建哪些网络?
当你安装 Docker 后,Docker 守护进程(dockerd
)自动创建了几个默认网络 。
你可以用命令查看:
bash
docker network ls
输出一般类似这样:
NETWORK ID NAME DRIVER SCOPE
9a8d7f2a2a00 bridge bridge local
cc3c8e21ab21 host host local
f3ac42e1d7c3 none null local
🌉 (1) bridge 网络(默认)
- 当你运行容器时(如果不指定网络),Docker 默认会把容器放到
bridge
网络中。 - 这是一个 由 Docker 自建的虚拟网桥(docker0)。
- 每个容器在这个网桥上都会被分配一个 私有 IP(172.17.0.x)。
- 容器之间可以互相通信(因为都在同一个二层网络里)。
🌐 (2) host 网络
- 容器直接使用宿主机的网络栈。
- 容器内没有自己的独立 IP,直接使用宿主机的 IP 和端口。
- 优点:性能高(少一层 NAT),但缺点是:端口容易冲突、隔离性差。
🚫 (3) none 网络
- 容器完全没有网络接口。
- 除了 loopback(127.0.0.1)外,无法通信。
- 常用于安全隔离或自定义网络方案。
🔗 2. bridge 模式下容器之间的通信原理
在 bridge
模式下(默认),Docker 会自动创建一个虚拟网桥:
宿主机
├─ docker0 (虚拟网桥, 类似交换机)
│ ├─ 容器1 eth0 → 172.17.0.2
│ └─ 容器2 eth0 → 172.17.0.3
-
每个容器的网络接口(eth0)都连接到
docker0
。 -
Docker 会给每个容器分配 IP,并写好路由表。
-
这样容器之间通过 IP(172.17.0.x)就能直接通信。
例如:
bashping 172.17.0.3
🌍 容器访问外网的原理
- 容器发出的流量,会经过
docker0
,然后由 Docker 的 NAT(源地址转换) 转换成宿主机的 IP 发出去。 - 外部网站看到的就是宿主机的 IP,而不是容器的。
- 返回数据再通过 NAT 映射回来。
所以容器访问外网的原理就是:
「容器 → docker0 → NAT → 宿主机网络 → 外网」
🔥 3. 宿主机防火墙在 Docker 网络中的角色
✅ Docker 与 iptables
Docker 启动时,会在宿主机的 iptables
中自动添加一些规则,用于:
- 容器间通信
- 容器访问外网(NAT)
- 端口映射(-p 参数)
如果你手动改动防火墙(或启用 firewalld 严格策略),可能导致:
- 容器无法上网;
- 容器端口无法访问;
- 容器间通信被阻断。
🧭 排查思路
-
检查 Docker 的 iptables 是否被禁用:
bashps -ef | grep dockerd
如果有
--iptables=false
,说明 Docker 不再自动管理防火墙。 -
查看 Docker 的 NAT 规则是否还在:
bashsudo iptables -t nat -L -n
应该能看到类似:
Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
-
若被 firewalld 阻断,可尝试允许 docker0:
bashsudo firewall-cmd --zone=trusted --add-interface=docker0 --permanent sudo firewall-cmd --reload
🚪 4. 端口映射解释:-p 8080:80
命令:
bash
docker run -p 8080:80 myapp
含义是:
把宿主机的 8080 端口 映射到容器的 80 端口。
数据流向:
浏览器访问 http://宿主机IP:8080
↓
宿主机防火墙检查通过
↓
iptables (DNAT 映射规则)
↓
容器内的 80 端口
↓
myapp 接收请求并返回响应
举例:
如果宿主机 IP 是 192.168.1.10
,那访问:
http://192.168.1.10:8080
就等同于访问容器的:
http://172.17.0.2:80