UP | HOME

docker网络

目录

docker_network.jpg

图1  docker network

四种单节点网络模式

bridge 模式

Docker 容器默认使用 bridge 模式的网络。其特点如下:

  • 使用一个 linux bridge,默认为 docker0
  • 使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上
  • 该模式下 Docker Container 不具有一个公有 IP,因为宿主机的 IP 地址与 veth pair 的 IP 地址不在同一个网段内
  • Docker 采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口 port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
  • 外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
  • NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
  • 容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过 NAT 建立通信

iptables 的 SNTA 规则,使得从容器离开去外界的网络包的源 IP 地址被转换为 Docker 主机的 IP 地址:

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination
    MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
    MASQUERADE  all  --  172.18.0.0/16        0.0.0.0/0

效果是这样的:

bridge.jpg

图2  bridge

示意图:

bridge_network.jpg

图3  bridge_network

Host 模式

Host 模式并没有为容器创建一个隔离的网络环境。 而之所以称之为 host 模式,是因为该模式下的 Docker 容器会和 host 宿主机共享同一个网络 namespace,故 Docker Container 可以和宿主机一样,使用宿主机的 eth0,实现和外界的通信。 换言之,Docker Container 的 IP 地址即为宿主机 eth0 的 IP 地址。其特点包括:

  • 这种模式下的容器没有隔离的 network namespace
  • 容器的 IP 地址同 Docker host 的 IP 地址
  • 需要注意容器中服务的端口号不能与 Docker host 上已经使用的端口号相冲突
  • host 模式能够和其它模式共存

示意图:

host_network.jpg

图4  host_network

container 模式

Container 网络模式是 Docker 中一种较为特别的网络的模式。 处于这个模式下的 Docker 容器会共享其他容器的网络环境,因此,至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。

注意:因为此时两个容器要共享一个 network namespace,因此需要注意端口冲突情况,否则第二个容器将无法被启动。

示意图:

container_network.jpg

图5  container_network

none 模式

网络模式为 none,即不为 Docker 容器构造任何网络环境。 一旦 Docker 容器采用了 none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。 Docker Container 的 none 网络模式意味着不给该容器创建任何网络环境,容器只能使用 127.0.0.1 的本机网络。

多节点 Docker 网络

Docker 多节点网络模式可以分为两类,一类是 Docker 在 1.19 版本中引入的基于 VxLAN 的对跨节点网络的原生支持; 另一种是通过插件(plugin)方式引入的第三方实现方案,比如 Flannel,Calico 等等。

Docker 原生 overlay 网络

Docker 1.19 版本中增加了对 overlay 网络的原生支持。 Docker 支持 Consul, Etcd, 和 ZooKeeper 三种分布式 key-value 存储。 其中,etcd 是一个高可用的分布式 k/v 存储系统,使用 etcd 的场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,但是更新访问频繁的情况。

网络拓扑图:

overlay_network.jpg

图6  overlay_network

可见:

  • Docker 在每个节点上创建了两个 linux bridge,一个用于 overlay 网络(ov-000100-1de98),一个用于非 overlay 的 NAT 网络(docker_gwbridge)
  • 容器内的到 overlay 网络的其它容器的网络流量走 overlay 网卡(eth0),其它网络流量走 NAT 网卡(eth1)
  • 当前 Docker 创建 vxlan 隧道的 ID 范围为 256~1000,因而最多可以创建 745 个网络,因此,本例中的这个 vxlan 隧道使用的 ID 是 256
  • Docker vxlan 驱动使用 4789 UDP 端口
  • overlay 网络模型底层需要类似 consul 或 etcd 的 KV 存储系统进行消息同步
  • Docker overlay 不使用多播
  • Overlay 网络中的容器处于一个虚拟的大二层网络中

网络性能对比

个人测试

使用 iperf 测试:

类型 TCP UDP
Overlay 网络中的两个容器之间 (A) 913 Mbits/sec 1.05 Mbits/sec
Bridge/NAT 网络中的两个容器之间 (B) 1.73 Gbits/sec  
主机间 (C) 2.06 Gbits/sec 1.05 Mbits/sec
主机到另一个主机上的 bridge 网络模式的容器 (D) 1.88 Gbits/sec  
主机到本主机上的容器 (E) 20.5 Gbits/sec  
主机到另一个主机上的 host 网络模式的容器 (F) 2.02 Gbits/sec 1.05 Mbits/sec
容器 Overlay 效率 (A/C) 44% 100% ?
单个 NAT 效率 (D/C) 91%  
两个 NAT 效率 (B/C) 83%  
Host 网络模式效率 (F/C) 98% 100%

网络文章的对比数据

perf_network.jpg

图7  perf_network

关于 Docker 网络模式选择的简单结论

  • Bridge 模式的性能损耗大概为 10%
  • 原生 overlay 模式的性能损耗非常高,甚至达到了 56%,因此,在生产环境下使用这种模式需要非常谨慎。
  • 如果一定要使用 overlay 模式的话,可以考虑使用 Cisco 发起的 Calico 模式,它的性能和 bridge 相当。
  • Weave overlay 模式的性能数据非常可疑,按理说应该不可能这么差。

作者: Petrus.Z

Created: 2021-09-01 Wed 00:38