DockerNetworkPerformanceTest

TurnToJPG -->


测试环境

Docker常用的两种网络模式包括Bridge和Host模式,为测试这两种网络模式的性能,我们将创建以下的测试环境:

两台服务器之间的物理网络为万兆以太网络。

我们采用Iperfhttp://software.es.net/iperf/来测量网络带宽,iperf非常简单,也拥有足够多的特性用于测试基本的性能指标。 在服务器端,我们需要一个运行iperf3的Docker容器。 Docker的版本为17.05-ce.

测试将基于以下几个场景:

原始网络吞吐量

首先,我们需要得到在没有任何Docker容器运行时的原始网络吞吐,在Server端运行:

[root@192.192.192.89 ~]# iperf3 -s -p 5202

Client端运行:

[root@192.192.192.88 ~]# iperf3 -c 192.192.192.89 -p 5202

运行测试后,服务器端和客户端都会返回诊断信息。我们暂时只关心其吞吐量:

-----------------------------------------------------------
Server listening on 5202
-----------------------------------------------------------
Accepted connection from 192.192.192.88, port 39682
[  5] local 192.192.192.89 port 5202 connected to 192.192.192.88 port 39684
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-1.00   sec  1.05 GBytes  9.05 Gbits/sec                  
[  5]   1.00-2.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   2.00-3.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   3.00-4.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   4.00-5.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   5.00-6.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   6.00-7.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   7.00-8.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   8.00-9.00   sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]   9.00-10.00  sec  1.10 GBytes  9.41 Gbits/sec                  
[  5]  10.00-10.04  sec  42.0 MBytes  9.39 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-10.04  sec  0.00 Bytes  0.00 bits/sec                  sender
[  5]   0.00-10.04  sec  11.0 GBytes  9.38 Gbits/sec                  receiver
-----------------------------------------------------------
Server listening on 5202
-----------------------------------------------------------

可以看到,在万兆交换机的网络场景下,物理机到物理机之间的网络带宽跑满了万兆交换机的极限.

跨主机物理机到Docker(host模式)

在Docker中运行iperf3相当简单,在hub.docker.com可以找到大量的打包有iperf3的镜像,我们采用:

# sudo docker pull networkstatic/iperf3

在服务器端启动侦听5203端口的docker实例:

[root@192.192.192.89 ~]# docker run --net=host  -it --rm --name=iperf3-server networkstatic/iperf3 -s -p 5203

在Client端执行对应的修改,得到的结果为:

[root@192.192.192.88 ~]# iperf3 -c 192.192.192.89 -p 5203
Connecting to host 192.192.192.89, port 5203
[  4] local 192.192.192.88 port 40326 connected to 192.192.192.89 port 5203
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  1.10 GBytes  9.43 Gbits/sec   20    625 KBytes       
[  4]   1.00-2.00   sec  1.10 GBytes  9.42 Gbits/sec    0    625 KBytes       
//.....

结果差不多相同: 9.40 Gbits/sec

跨主机物理机到Docker(Bridge模式)

更改为5204端口,这次使用的网络模式为Bridge模式:

[root@192.192.192.89 ~]# docker run  -it --rm -p 5204:5204 --name=iperf3-server networkstatic/iperf3 -s -p 5204

在客户端不作任何修改,只更换远端端口为5204:

[root@192.192.192.88 ~]# iperf3 -c 192.192.192.89 -p 5204
Connecting to host 192.192.192.89, port 5204
[  4] local 192.192.192.88 port 53936 connected to 192.192.192.89 port 5204
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  1.10 GBytes  9.44 Gbits/sec   15    669 KBytes       
[  4]   1.00-2.00   sec  1.10 GBytes  9.42 Gbits/sec    0    682 KBytes       
[  4]   2.00-3.00   sec  1.10 GBytes  9.42 Gbits/sec    0    691 KBytes 

可以看到,在Bridge模式下,吞吐量也跑满了万兆网络的极限.

同主机物理机到Docker(Bridge模式)

在同一台主机上(192.192.192.89)上运行iperf,测试到Docker的吞吐量,沿用之前侦听5204的容器不变:

[root@192.192.192.89 ~]# iperf3 -c 192.192.192.89 -p 5204
Connecting to host 192.192.192.89, port 5204
[  4] local 192.192.192.89 port 46720 connected to 192.192.192.89 port 5204
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  2.77 GBytes  23.8 Gbits/sec    0    274 KBytes       
[  4]   1.00-2.00   sec  2.75 GBytes  23.6 Gbits/sec    0    274 KBytes       
[  4]   2.00-3.00   sec  2.75 GBytes  23.6 Gbits/sec    0    277 KBytes       

在这种模式下,网络的吞吐量几乎三倍于万兆网络,这是因为从主机到Docker实例的网络通路会走本地的回环接口(lo-loopback)接口。

同主机Docker到Docker(Bridge模式-external)

沿用侦听5204端口的容器不变,新启动一个容器,在其中运行iperf:

# iperf3 -c 192.192.192.89 -p 5204
Connecting to host 192.192.192.89, port 5204
[  4] local 172.17.0.5 port 59574 connected to 192.192.192.89 port 5204
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  1.03 GBytes  8.84 Gbits/sec   91    228 KBytes       
[  4]   1.00-2.00   sec   955 MBytes  8.01 Gbits/sec    0    229 KBytes       
[  4]   2.00-3.00   sec  1.02 GBytes  8.80 Gbits/sec    0    230 KBytes       
[  4]   3.00-4.00   sec   767 MBytes  6.43 Gbits/sec    0    230 KBytes       
[  4]   4.00-5.00   sec   851 MBytes  7.14 Gbits/sec    0    230 KBytes       

可以看到,如果直接使用物理机的IP地址和端口,则吞吐需要同时使用Bridge模式下物理网卡的吞吐, 此时网卡的物理性能下降明显。

同主机Docker到Docker(Bridge模式-internal)

为了避免使用物理机的IP地址带来的性能下降,直接使用容器内部的IP地址做iperf测试:

# iperf3 -c 172.17.0.4 -p 5204
Accepted connection from 172.17.0.5, port 39516
[  5] local 172.17.0.4 port 5204 connected to 172.17.0.5 port 39518
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-1.00   sec  2.39 GBytes  20.5 Gbits/sec                  
[  5]   1.00-2.00   sec  2.50 GBytes  21.5 Gbits/sec                  
[  5]   2.00-3.00   sec  2.50 GBytes  21.5 Gbits/sec 

可以看到,在这种模式下,容器之间的通信还是基于lo(loopback)接口来做的,几乎三倍于万兆交换机的峰值速度。

结论

各次测试的对比数据整理如下:

| 物理机-物理机                           | 9.40 Gbit/sec    | 100%  |
| 跨物理机到Docker(host模式网络)          | 9.40 Gbit/sec    | 100%  |
| 跨物理机到Docker(Bridge模式网络)        | 9.40 Gbit/sec    | 100%  |
| 同主机内到Docker(Bridge模式网络)        | 23.8 Gbit/sec    | 250%  |
| 同主机Docker到Docker(Bridge模式-ex)     | 8.00 Gbit/sec    |  85%  |
| 同主机Docker到Docker(Bridge模式-int)    | 21.00 Gbit/sec   | 220%  |

结论: 在Docker运行环境中,网络的吞吐量近似于本地网络IO,基本上不会有性能损耗。需要特别注意的是,一定要避免同主机中的Docker实例彼此使用物理机IP/端口进行通信,那样会带来性能的明显下降。