今天一个从来没有用过docker容器的同事问了我一个网络延迟的问题,很简单,但我确没有准确回答出来。经过简单的验证,现在我把过程及结果分享给各位粉丝。
简短对话
容器中的网络延迟相较于宿主机有多高啊?
我不假思索的回答可以忽略不计吧
同事带着疑惑的的说了句,那你说说docker网络桥接的实现
在容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0,另一端放在宿主机中;docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关;这样它们就组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。相当于多了一层网络,就少不了网络解封包开销,看来是有影响的。
影响到底有多大呢?没有做过这方面的测试......
验证环境准备
本次验证工具我使用了Netperf,Netperf是一种网络性能的测量工具,可以测试基于TCP或UDP吞吐、响应速率。Netperf包括Clien和Server端。Server端主要用来实现监听工作,Client端进行测试。根据流量传输方式可分为以下三种:
- 单方向最大吞吐传输大量数据。
- 双方向交互传输数据,对于tcp为单连接。
- 针对tcp,每个连接交互传输数据。
环境信息
总共两台机器,一台机器启动了NetPerf服务端;另外一台机器分别在容器内和宿主机上运行Netperf客户端。
NetPerf服务端
1.下载wget http://repo.iotti.biz/CentOS/7/x86_64/netperf-2.7.0-1.el7.lux.x86_64.rpm
2.安装 rpm -ivh netperf-2.7.0-1.el7.lux.x86_64.rpm
3.启动 netserver
NetPerf客户端
宿主机验证
首先直接在宿主机上安装Netperf,然后进行网络性能测试,如下所示:
TCP_RR 是 netperf 里专门用来测试网络延时的,缺省每次运行10秒钟。运行以后,我们还要计算平均每秒钟 TCP request/response 的次数,这个次数越高,就说明延时越小。如上所示,总共测试三轮,分别得出20146、20248、20221,平均是20221/s
容器中验证
在同一台客户端机器上,启动docker服务,并安装Netperf进行验证,命令如下所示[root@test ~]# docker run -d --name test -v /home/net/:/home/net/ docker.harbor.com/centos:7.8 sleep 36000
我这里相当于是把Netperf挂载到容器内部,然后执行:
docker exec -it test bash
进入容器内部安装Netperf。
同样运行了三轮,分别得出的是19546、19541、19259,平均是19448/s。
从数据上看容器中比宿主机少了773次。773/20221= 4%也就是容器中网络处理速度下降了4%,后来在网上找到了一些paper,有人得出结论是10%上下
。
容器中共享宿主机网络运行
[root@test ~]# docker run -d --name test --network host -v /home/net/:/home/net/ docker.harbor.com/centos:7.8 sleep 36000
可以发现当使用共享宿主机网络模式下,其网络延迟跟宿主机基本没有差异。
原因分析
网络延迟的原因也不难想象,因为每次网络数据传输都要经过veth接口,然后向外发送。这个虚拟的网络设备除了没有硬中断,只有软中断处理过程,其它跟网卡发送数据逻辑基本相似,虽然发送速度很快。但即便如此也带来了一定的网络开销,从而造成了网络延迟。