总结

总结

我目前已经在几个 OpenStack 托管的虚拟机上运行了 Docker。

当尝试从这些机器上的容器内发出 HTTP 请求时,请求几乎总是会挂起等待响应。当发出 HTTPS 请求时,请求总是会超时,因为它无法完成 TLS 握手。无论哪种情况,请求似乎在仅收到几百字节的响应数据(如果有的话)后就失败了。相同的请求在主机上没有任何问题地完成(即问题不是主机级防火墙)。

我遇到过(以及一些相关的博客文章)表明这可能是由于 Docker 网桥与主机网络接口的 MTU 不同,但我已经验证了两个 MTU 是相同的(每种情况下都是 1500 字节)。我还尝试过切换--mtu到 Docker 守护程序,看看是否可以让它工作,但没有成功。

我还遇到过一些类似的情况,这些情况表明这可能是由于 TCP 校验和和/或分段卸载造成的(例如这里),但无论怎么玩弄ethtool -K {interface} tx off rx off或类似的东西都不会产生任何积极的结果。

这种行为似乎特定于网桥 ---net=host在运行容器时使用确实可以解决问题。但是,出于安全原因,我希望避免在我们的生产系统中使用此解决方法。

还要注意,完全相同的设置(相同的 Docker 版本、相同的配置参数)在我的开发机器上或在 AWS 托管的实例上运行时运行良好 - 无论问题是什么,它似乎只有在 OpenStack 下运行时才会显现出来。

作为参考,我使用以下命令进行测试:

docker run -it alpine:3.3 wget http://ipv4.download.thinkbroadband.com/5MB.zip

理论上,运行时该命令应该会下载一个 5MB 的测试文件。但是,wget命令只是挂起。可能还值得注意的是,问题不在于客户操作系统 - 使用 Ubuntu 映像(例如)仍然会出现相同的行为。

我和一位同事还使用 netcat 进行了一些文件传输测试。在这些测试中,我们能够成功地将文件从容器传输到我们的测试服务器,但尝试反向传输失败。我们还曾tcpdump在这些测试期间捕获网络活动 - 在失败的测试期间,日志显示收到了一些数据包,但数量明显少于预期。

docker version此外,如果相关的话,这里是相关系统的输出:

Client:
 Version:      1.12.1
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   23cf638
 Built:        Thu Aug 18 05:22:43 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.1
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   23cf638
 Built:        Thu Aug 18 05:22:43 2016
 OS/Arch:      linux/amd64

主机上的输出uname -a如下:

Linux docker-builder-1 4.4.0-38-generic #57~14.04.1-Ubuntu SMP Tue Sep 6 17:20:43 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

更新

事实证明,如果 Docker 托管在 Ubuntu 16.04 镜像下,一切都会按预期工作。

此时,我可以继续重建所有虚拟机以使用 Ubuntu 16.04 映像,但我仍然不知道原始问题是什么。我仍然有兴趣听取有关原始问题的原因以及如何修复它的任何建议。

答案1

总结

将 dockerd MTU 标志适配到您的 VM 的 MTU。

例子

我的一个OpenStack实例的操作系统是ubuntu16.04。

  1. 检查虚拟机的 MTU ifconfig(我的情况是 1450)
  2. cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
  3. vi /etc/systemd/system/docker.service
  4. ExecStart=/usr/bin/docker daemon -H fd:// --mtu 1450
  5. systemctl daemon-reload
  6. service docker restart

相关内容