如何从主机到Docker容器的网络吞吐量非常低?
与从主机到同一主机发送的流量相比,当将数据从主机机器发送到Docker容器时,我经历的网络性能极为弱。
测量TCP性能
我已经 | 使用 iperf 来 | 。 | 带宽(用IPER进行测量,请参见下文) |
---|---|---|---|
MacOS | 主机 | Windows | 〜56.3 GBITS/sec |
macOS | 主机 | 容器 | 〜350 mbits/sec |
Pro | 主机 | 〜5 | 10 gbit/sec |
Windows Pro 10 | 主 | 容器 | 〜680 mbit/sec |
命令运行以获取结果:
iperf -s -p 8020 # on the server side (receiving data)
iperf -c -p 8020 # on the client side (sending data)
我正在以网络桥模式(默认值)运行docker容器(默认值)并发布端口8020(网络主机模式不适合MACOS) 。
这些结果似乎非常直觉:首先,在操作系统上,码头容器和主机机器之间的测量带宽急剧低于宿主到主机连接的可用带宽。这是为什么?致力于Localhost的AFAIK数据包通常不是由NIC来处理的,而是由OS/内核本身处理,因此它们不应依赖NIC的可用带宽。尽管每个Docker容器都使用自己的网络界面,但我认为该网卡也不涉及那里(这可能是带宽/性能差的可能原因)。
其次,似乎很奇怪的是,Windows上的平均带宽比MacOS高于主机到容器连接的MACO,即使我们在MACOS上获得了更高的带宽,用于主机到主机连接。
为什么我们在地球上会遇到如此糟糕的带宽,用于寄宿至容器包装?这是Docker容器的已知问题(我们在Internet上找不到与此相同结果跨平台相同的任何内容)?有什么好方法可以规避/解决此问题吗?
I'm experiencing extremely weak network performance when sending data from a host machine to a docker container, compared to traffic sent from a host machine to the same host.
I've measured the TCP performance using iPerf, these are the results on different operating systems with Docker installed:
Operating System | Client | Server | Bandwidth (measured with iPerf, see below) |
---|---|---|---|
macOS | Host | Host | ~56.3 Gbits/sec |
macOS | Host | Container | ~350 Mbits/sec |
Windows Pro 10 | Host | Host | ~5 Gbit/sec |
Windows Pro 10 | Host | Container | ~680 Mbit/sec |
The command run to get the results:
iperf -s -p 8020 # on the server side (receiving data)
iperf -c -p 8020 # on the client side (sending data)
I'm running the Docker containers in networking bridge mode (default) and publishing the port 8020 (network host mode is not available for macOS).
These results seem very unintuitive: First of all, on both operating system the measured bandwidth between a Docker container and the host machine falls drastically below the available bandwidth of a host-to-host-connection. Why is that? Afaik packets addressed to localhost are generally not handled by the NIC but rather by the OS/kernel itself, so they shouldn't depend on the NIC's available bandwidth. Although each Docker container uses its own network interface, I don't think the network card is involved there either (which could be a possible cause for a limited bandwidth/poor performance).
Secondly, it seems weird that the average bandwidth on Windows is higher than on macOS for host-to-container connections, even though we've achieved a much higher bandwidth on macOS for host-to-host connections.
Why on earth do we experience such a poor bandwidth for host-to-container packets? Is this a known issue with Docker containers (we couldn't find anything related to this on the internet that has the same results cross-platform)?Is there a good way to circumvent/fix this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
回环接口的最大传输单元(MTU)往往很大。例如,运行12.4的Mac的“ LO0”接口是16384字节。相比之下,您可能会查看Docker界面的MTU。 TCP依靠大型MTU和/或无状态卸载(校验和卸载/cko和TCP分割卸载/tso和大/通用接收卸载/[lg] ro)来实现高比特率达到给定的比特率。
例如,如果Docker界面的MTU是1500个字节而不是16384,并且也没有无状态的卸载,则您希望基于Docker的测试需要大约16384/1500或约10倍的数量。作为简单的回环,在协议堆栈上下行程。而且,这将是更长的基本代码路径。如果通过回环而不是案卷接口可用,则差异将更大。在那些到位的情况下,TCP可以表现得好像MTU最多为64 KIB一样。
如果除了IPERF批量传输测试外,您还运行了类似Netperf TCP_RR测试的内容,您将获得第一个近似值,即Pline Loopback和Docker配置之间的基本数据包路径长度差异。
The Maximum Transmission Unit (MTU) of the loopback interface tends to be rather large. For example, the "lo0" interface of my Mac running 12.4 is 16384 bytes. You might look at the MTUs of the Docker interfaces in comparison. TCP relies on large MTUs and/or stateless offloads (ChecKsum Offload/CKO and TCP Segmentation Offload/TSO and Large/Generic Receive Offload/[LG]RO) to achieve high bitrates by minimizing the number of trips up and down the protocol stack required to achieve a given bitrate.
If, for example, the MTU of the Docker interface(s) is 1500 bytes rather than 16384, and there aren't also stateless offloads, you would expect the Docker-based test to need roughly 16384/1500 or ~10 times as many trips up and down the protocol stack as a plain loopback. And, it will be a longer fundamental code path on top of that. The difference would be even greater if TSO/GRO were available via the loopback and not the Docket interfaces. With those in place a TCP can behave as if the MTU was up to 64 KiB.
If you run something like a netperf TCP_RR test in addition to your iperf bulk transfer test, you will get a first approximation of the difference in basic packet path length between the plain loopback and Docker configurations.