docker中网络实现原理

当 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 就创建了在主机和所有容器之间一个虚拟共享网络。
image.png

docker网络配置参数

  • -b BRIDGE--bridge=BRIDGE 指定容器挂载的网桥
  • --bip=CIDR 定制 docker0 的掩码
  • -H SOCKET...--host=SOCKET... Docker 服务端接收命令的通道
  • --icc=true|false 是否支持容器之间进行通信
  • --ip-forward=true|false 请看下文容器之间的通信
  • --iptables=true|false 是否允许 Docker 添加 iptables 规则
  • --mtu=BYTES 容器网络中的 MTU

下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 docker run 时可以覆盖设置的默认值。

  • --dns=IP_ADDRESS... 使用指定的DNS服务器
  • --dns-search=DOMAIN... 指定DNS搜索域

这些选项只有在 docker run 执行时使用,因为它是针对容器的特性内容。

  • -h HOSTNAME--hostname=HOSTNAME 配置容器主机名
  • --link=CONTAINER_NAME:ALIAS 添加到另一个容器的连接
  • --net=bridge|none|container:NAME_or_ID|host 配置容器的桥接模式
  • -p SPEC--publish=SPEC 映射容器端口到宿主主机
  • -P or --publish-all=true|false 映射容器所有端口到宿主主机

容器访问外部网络

容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开
image.png
如果为0需打开sysctl -w net.ipv4.ip_forward=1
docker run -d -P nginx:alpine创建容器并随即端口访问外部
iptables -t nat -nL 查看iptables配置
image.png
上述规则将所有源地址在 172.17.0.0/16 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。
image.png

  • 这里的规则映射了 0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 -p IP:host_port:container_port-p IP::port 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。
  • 如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容。
{

"ip": "0.0.0.0"

}

docker0 网桥

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。

  • --bip=CIDR IP 地址加掩码格式,例如 192.168.1.5/24
  • --mtu=BYTES 覆盖默认的 Docker mtu 配置

也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。

由于目前 Docker 网桥是 Linux 网桥,用户可以使用 brctl show 来查看网桥和端口连接信息。

image.png
每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 docker0 接口的 IP 作为所有容器的默认网关。
image.png

创建一个点到点连接


Cherish
216 声望4 粉丝