Docker 默认网络
核心概念 —— docker0、veth-pair
docker0 —— 虚拟交换机
什么是 docker0:docker0 是一个虚拟桥接网络,即虚拟交换机。
veth-pair 技术
它是一对虚拟的、点对点直接链路。
把这两句串起来理解整个过程:
宿主机
├── docker0(虚拟交换机,有自己的 IP,通常是 172.17.0.1)
│
├── veth 一对网线的一端 ←→ 容器里的 eth0(网线的另一端)
├── veth 一对网线的一端 ←→ 容器里的 eth0
└── ...
所以:
· 每个容器都有一根"虚拟网线"(veth-pair)插到 docker0 这个虚拟交换机上
· 同一台宿主机上的容器,通过 docker0 二层互通
实操验证:看容器的网卡和 IP
docker run -d --name tomcat01 -P tomcat:7
docker run -d --name tomcat02 -P tomcat:7
docker exec tomcat01 ip addr # 容器里有一块 eth0,IP 形如 172.17.0.x
docker inspect -f '{{.NetworkSettings.IPAddress}}' tomcat01
docker inspect -f '{{.NetworkSettings.IPAddress}}' tomcat02
ip addr show docker0 # 宿主机上的 docker0,IP 通常是 172.17.0.1
注意:这两条
docker run用的是-P(大写),也就是让 Docker 随机分配宿主机端口。用docker port tomcat01可以看到实际映射到了哪个端口(一般是 32768 起)。
四种网络模式
| 模式 | DRIVER | 说明 |
|---|---|---|
| Bridge | bridge | 默认模式(桥接,自己创建的网络也是用它)。此模式会为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,通过 docker0 网桥以及 iptables nat 表配置与宿主机通信 |
| Host | host | 容器没有独立网络命名空间,不会虚拟出自己的网卡、也不配置独立 IP,而是直接使用宿主机的 IP 和端口 |
| None | null | 该模式关闭了容器的网络功能(一般不用) |
| 自定义(container) | — | 加入另一个已存在容器的网络命名空间(了解即可) |
Host 模式要注意什么:因为直接用宿主机网络,所以不能做端口映射(
-p会失效并可能报错),而且容器里ss -lntp看到的是宿主机所有的端口。适合做网络性能敏感的场景(少了 NAT 一层)。None 模式:给了你一个完全没有网络的容器,通常用于"我自己来配网络"的高级场景,或者做纯计算任务。
自定义网络
现有的网络模式不一定适合所有场景,有时候我们要自定义一个网络。
docker network create --driver bridge --subnet 192.168.100.0/24 --gateway 192.168.100.1 hangnet
docker run -d -P --name=tomcat04 --net hangnet tomcat:7
docker run -d -P --name=tomcat05 --net hangnet tomcat:7
检验(这一步很关键):
docker network ls # 能看到 hangnet
docker network inspect hangnet | grep -A3 Subnet # 能看到 192.168.100.0/24
docker inspect -f '{{.NetworkSettings.IPAddress}}' tomcat04 # 192.168.100.x
docker inspect -f '{{.NetworkSettings.IPAddress}}' tomcat05
# ★ 关键验证:同一个自定义网络里,容器可以互相 ping 通(默认用容器名就能通)
docker exec tomcat04 ping -c 2 tomcat05
★ 自定义网络 vs 默认 bridge 网络 —— 最重要的一个区别:
| 对比项 | 默认 bridge | 自定义网络(bridge driver) |
|---|---|---|
| 容器之间能否用容器名通信 | 不能(只能靠 IP,而且 IP 会变) | 能(内置 DNS 解析) |
| 网段 | 固定 172.17.0.0/16 | 自己指定 |
| 隔离 | 所有容器混在一起 | 按网络隔离,不同网络不互通 |
清理实验环境:
docker rm -f tomcat01 tomcat02 tomcat04 tomcat05
docker network rm hangnet
容器对外服务(SNAT / DNAT)
① 容器可以上网的原理,是利用 iptables 的 SNAT 技术(SNAT = 源地址转换)。
② 容器服务能被外部访问,是利用了 iptables 的 DNAT 技术(DNAT = 目标地址转换)。
【出方向 / 容器访问外网 → SNAT(源地址转换)】
容器(172.17.0.3) → 请求发到 docker0 → 宿主机把【源地址】改成自己的 IP
→ 发到外网 → 回包回到宿主机 → 宿主机再转回容器
为什么必须改:172.17.0.3 是私网地址,外网不知道怎么回包
【入方向 / 外部访问容器 → DNAT(目标地址转换)】
外部用户访问 宿主机IP:8080
→ PREROUTING 链上被 DOCKER 链匹配到
→ 把【目标地址】改成 172.17.0.3:80
→ 转给容器,容器以为是直接连它
这就是 -p 8080:80 背后真正发生的事