介绍

docker有4种网络通信模型,分别是:bridge、host、none、container
默认的使用的网络模型是bridge,也是我们生产上会使用到的网络模型。

host 宿主机网络

与主机共享网络协议栈
Host模式使用是在容器启动时候指明—network host,此时容器共享宿主机的Network Namespace,容器内启动的端口直接是宿主机的端口,容器不会创建网卡和IP,直接使用宿主机的网卡和IP,但是容器内的其他资源是隔离的,如文件系统、用户和用户组。直接使用宿主机网络。同样启动一个nginx,此时共享主机网络,根据情况来使用,这样子也不用做端口转发,网络传输效率会比较高(思考一下为什么)。
示例

  1. docker run --rm=true -itd --name=ubuntu_host --network=host ubuntu:20.04

Docker有几种网络通信模型 - 图1

bridge 桥接网络 NAT 技术

各个容器之间网络协议栈单独分离
当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。
当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
如图所示,同一个主机的两个容器之间通过网桥doker0进行通信。(不同之间的主机上的容器通信需要借助overlay网络,涉及到一些底层协议,单独写一篇文章拿出来讲)
示例

  1. docker run --rm=true -itd --name=ubuntu_host --network=bridge ubuntu:20.04

默认情况网络下即为 bridge, 所以--network=bridge 可以不用填写
Docker有几种网络通信模型 - 图2

joined 联合挂载式网络模式

容器之间可以共享网络协议栈,即可以通过套接字来进行通信
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
示例

  1. docker run --rm=true -itd --name=ubuntu_a ubuntu:20.04
  2. docker run --rm=true -itd --name=ubuntu_b --network=container:ubuntu_a ubuntu:20.04

以上示例, 进入 ubuntu_b 你会发现, ip 和 ubuntu_a 是同一个IP
容器 ubuntu_b 使用了容器 ubuntu_a 的网络, 当容器 ubuntu_a 的网络发生变化,容器 ubuntu_b 的网络也跟着变化
Docker有几种网络通信模型 - 图3

macvlan 网卡虚拟化方案

首先,从网上我们可以看到,macvlan 技术就是在物理网卡下,添加另一张虚拟网卡,其实就是在物理网卡下添加了一个条件分支。我们可以认为报文从物理网卡进入之后,会做一个switch判断,如果该报文mac属于 macvlan,则直接发往macvlan后面的网络,否则就发往原host的网络。这里简单的做个试验就知道了。
image.png
可以使得容器与宿主机在同一个物理交换机下, 有独立的 IP 地址
Docker有几种网络通信模型 - 图5

了解更多详情 https://www.yuque.com/uuu/docker/macvlan

none 不附加任何网络

相当于一座孤岛,没有网络协议栈的通信
在容器启动是不附加任何网络, 可以通过 veth-pair 技术实现网络添加,
大多数情况下, 联合网桥使用
常应用于定制化程度高复杂的网场景,
使用none模式,Docker容器拥有自己的 Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息,只有lo 网络接口。需要我们自己为Docker容器添加网卡、配置IP等