Ubuntu上的Docker无法饱和CPU

我有一个简单的Ruby应用程序,基本上它通过HTTP端点获取一些数据,稍微处理它,将它分组并将其批量发送到某个远程HTTP端点。

当我在裸机上运行时 – 我将4个CPU饱和到100%,并获得大约3000reqs/s (根据ab ;应用程序有点计算密集型);

但是当我在Docker中运行它时,我只能得到1700reqs/s – CPU似乎在55-65%左右达到峰值。 相同的应用程序,相同的设置。

CPU的

我试图增加ab的并发性。 该应用程序本身是托pipe在乘客,我试图运行在20个进程中,在40个进程(乘客运行应用程序)。 在Docker内部,似乎并不想走高。

我通过docker-compose运行它,主机是Ubuntu 14.04

 $ docker -v Docker version 1.10.0, build 590d5108 $ docker-compose -v docker-compose version 1.5.2, build 7240ff3 

在这两种情况下(大约20)的平均负载都很高,但是并不是光盘绑定的。

 $ vmstat 1 procs -----------memory---------- ---swap-- -----io---- ---system--- ------cpu----- rb swpd free buff cache si so bi bo in cs us sy id wa st 22 0 0 8630704 71160 257040 0 0 29 6 177 614 3 1 94 1 0 7 0 0 8623252 71160 257084 0 0 0 16 9982 83401 46 12 43 0 0 43 0 0 8618844 71160 257088 0 0 0 0 9951 74056 52 10 38 0 0 17 0 0 8612796 71160 257088 0 0 0 0 10143 70098 52 14 34 0 0 17 0 0 8606756 71160 257092 0 0 0 0 11324 70113 48 15 37 0 0 31 0 0 8603748 71168 257104 0 0 0 32 9907 85295 44 12 41 3 0 21 0 0 8598708 71168 257104 0 0 0 0 9895 69090 52 11 36 0 0 22 0 0 8594316 71168 257108 0 0 0 0 9885 68336 53 12 35 0 0 31 0 0 8589564 71168 257124 0 0 0 0 10355 82218 44 13 43 0 0 

这也不是networking绑定的。 即使我禁止发送数据到远程主机,所有通信都在机器内 – 我仍然看到55-65%。

docker和撰写的设置是默认的,没有任何调整。

为什么在Docker中运行时不能使CPU饱和? Docker中有一些隐藏的限制吗? 我如何发现这个限制?

EDIT1 CPU集,CPU份额

cpuset_cpus:0,1,2,3,4,5,6,7和/或cpu_shares: 102400 (100次默认值)似乎没有改变的情况。

/var/log/*也没有什么有趣的限制

EDIT2桥/主机networking

这也不是dockerbridgenetworking。 当我在Docker Compose中使用net: host时候效果是一样的

EDIT3比例

如果我用不同的端口暴露相同的代码运行第二个容器 – 我可以得到高达77%的CPU负载,但仍然不是裸机上的100%。 请注意,每个这些容器运行20-40个进程负载均衡与Passenger里面。

编辑4 Ubuntu的问题?

好吧,这似乎与Ubuntu有关。 在CoreOS上运行相同的容器 – 我能够饱和所有内核。

htop核心操作系统

但是我还是不明白这个限制。

EDIT5 DigitalOceantesting

为了完全公平,我在法兰克福数据中心的DigitalOcean上使用了2个相同的16GB 8CPU实例。 我在最新的Ubuntu和最新的CoreOS Alpha上安装了应用程序。

 CoreOS 949.0.0: Docker version 1.10.0, build e21da33 Ubuntu 14.04.3: Docker version 1.10.0, build 590d5108 

我不知道如何得到完全相同的构build – 似乎CoreOS有Docker内置和只读FS和Ubuntu – 我不知道如何获得构build完全e21da33。 但通用版本是相同的1.10.0

我也在法兰克福数据中心的DigitalOcean上从外部机器运行ab ,以确保ab不是变化。 在这两种情况下,我都遇到了外部IP。 ab的参数是相同的( ab -n 40000 -c 1000 -k ),代码是一样的。

结果:

  Ubuntu: 58-60% CPU 1162.22 [#/sec] (mean) CoreOS: 100% CPU 4440.45 [#/sec] (mean) 

这开始变得很奇怪。 htop比较

为了给Ubuntu一些机会,我也尝试添加:

  security_opt: - apparmor:unconfined 

但是这并没有太大的改变。

EDIT6在其他一些操作系统下testing过的容器:

 Ubuntu 14.04.3 NOT OK (50-60% CPU) Ubuntu 15.10 NOT OK (50-60% CPU) Debian 8.3 NOT OK (50-60% CPU) CentOS 7.2.1511 OK (100% CPU) CoreOS 949.0.0 OK (100% CPU) 

仍然不知道有什么限制。 似乎是Debian相关的。

请不要激动(或者激发我) – 这不是答案 – 我只是需要更多的空间而不是评论允许! 我不是Linux或Docker专家,但是我真的很喜欢这种问题,并且在周末做了一些研究,并且有一些可能的帮助。 我没有试验台,所以陷入了僵局。

迄今为止的理论“对于Debian和Ubuntu …”:

  1. Docker将容器和subprocess放入一个以某种方式受到限制的cgroup中。

  2. OS的调度程序和Docker容器中的调度程序(systemd?)在某种程度上与CPU“战斗”,并且不断地相互replace。

  3. 操作系统调度程序将(a)Docker Container和(b)应用程序视为单独的竞争资源请求,因此将每个约50%

  4. 在我看来,Linux的RedHat风格在某种程度上具有“集成”的docker(阅读“看它做了什么,并调整了他们的操作系统设置或Docker设置兼容”)。 他们做了什么改变呢? – 这可能是造成差异的原因。

  5. 强烈推动在RHEL 6下不使用Docker,而是使用RHEL 7+ – 在这些版本之间,RH有什么变化? CPU调度,使他们如此热衷于使用7 +?

接下来我要看的是:

  • 运行时cgroup设置。
  • 任何limits.conf文件的内容
  • Dockerconfiguration文件在RH和Ubuntu版本之间的差异。
  • (如果我有时间)看看RHEL 6上的Docker是否有问题(因为RHEL 7没有)

研究: https : //goldmann.pl/blog/2014/09/11/resource-management-in-docker/
http://www.janoszen.com/2013/02/06/limiting-linux-processes-cgroups-explained/
https://github.com/docker/docker/issues/6791
https://github.com/ibuildthecloud/systemd-docker/issues/15
https://unix.stackexchange.com/questions/151883/limiting-processes-to-not-exceed-more-than-10-of-cpu-usage
http://linux.die.net/man/5/limits.conf
https://marketplace.automic.com/details/centos-official-docker-image
https://www.datadoghq.com/blog/how-to-monitor-docker-resource-metrics/
https://libraries.io/go/github.com%2Fintelsdi-x%2Fsnap-plugin-collector-docker%2Fdocker
https://serverfault.com/questions/356962/where-are-the-default-ulimit-values-set-linux-centos
https://www.centos.org/forums/viewtopic.php?t=8956
https://docs.mongodb.org/manual/reference/ulimit/
http://www.unixarena.com/2013/12/how-to-increase-ulimit-values-in-redhat.html

如果这些都没有帮助我道歉!

systemd启动Docker修复了我的问题(Unbuntu 16.04)。 基准testing时,我所有的12个线程都在一个容器中100%使用。

停止Docker服务:

 sudo service docker stop 

并用systemctl启动它:

 sudo systemctl start docker 

在启动时启动Docker:

 sudo systemctl enable docker 

我们有同样的问题,开始潜水,发现这个: https : //www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt

您可以指定–cpu-quota到Docker,并且您希望它与您希望使用的CPUS数量相对应。

例如,如果您希望容器能够使用4个CPU,则应将其设置为400000.如果您希望容器完全不受限制,请指定-1。

为我们工作。