初探
Docker 有 4 种网络模式
- bridge
- container
- host
- none
其中 bridge
none
在 clone 时使用了 CLONE_NEWNET flag,但 none
仅做了 NETWORK NAMESPACE 但不进行资源设置分配,因而只能访问 loopback 设备(linux 下是 lo,虚拟网卡)
bridge 模式
这是 Docker 的默认网络模式,也是开发者常用的模式。实现了容器与宿主机、容器与容器间的网络栈隔离。
使用 veth pair 技术,一端接入到某个容器,另一段接入网桥 docker0(bridge),实现大致如下:
- 创建一对 veth pair,假设为 veth0 和 veth1
- 将 veth1 接入到 docker0,使得内部通过宿主机可以向外界发数据
- 将 veth0 接入到容器端,并改名为 eth0。实现互通
docker0
容器分配的 IP 与宿主机所在 IP 不处于同一网段,常用的默认 IP 段是 172.17.0.0/16。
docker0 使用 IP Forward 将容器上的服务暴露出来,将 容器 IP 和 服务端口
与 宿主机的端口
进行绑定。
从容器内部向宿主机外部发送数据
- 访问时内核为进程分配一个可用的端口
- 容器内部发送数据通过 eth0(即 veth0) 发送到 veth1(在 docker0 上)
- docker0 通过 ip forward 将数据包发送到宿主机的 eth0 上
- 宿主机监测到 iptables 规则,并对其进行 SNAT。将数据包中的源地址替换为宿主机的外网 IP,端口替换为之前绑定到
宿主机的端口
- 宿主机通过外网向目标 IP 发送数据
容器接收来自宿主机外部的数据
- 外界向容器绑定在宿主机的
IP
和端口
发送数据 - 宿主机收到数据后,因为存在 DNAT 规则。将对接收到的数据包中的
IP 和端口
进行替换为容器 IP 和端口
- 因宿主知道目标 IP 是容器的 IP,故向
docker0
发送修改后的数据包 - docker0 通过 veth pair 将数据包发送到制定容器的 eth0 上
实现功能
- 隔离容器的网络栈
- 通过 NAT 实现网络互通
缺点
- 宿主机的网络端口依旧有限,容器还是需要对端口进行竞争
- NAT 模式位于第三层网络,网络性能降低
container 模式
无需创建 veth pair
创建过程
- 查找指定容器的 network namespace(假设为 n1)
- 将本次创建容器的 network namespace 设为 n1
host 模式
与宿主机 共享网络栈
创建过程
- 创建容器时,clone 不带 CLONE_NEWNET
优点
无需通过 NAT,使容器获得宿主机的网络性能
缺点
共享网络栈,缺少隔离,端口资源争用
none 模式
这种情况下,容器只能访问内部网络,无法与其他容器、宿主机通信
创建过程
- 创建容器时,clone 传入 CLONE_NEWNET 但不对网络进行配置