我们每天在数百台服务器上运行成百上千个容器。我们面临的最大挑战之一是怎样高效地调度容器。从这个意义上说,调度是管理容器分配到一组服务器,以保持平稳的运行。因为我们调度的容器是客户应用程序的组件,我们必须在了解它们的运行特性前调度它们。
差的调度方法会导致以下两种可能的结果之一:
- 过多的资源配置——意味着更高的成本。
- 过少的资源配置——意味着用户的稳定性差。
正确的资源配置很重要,可以在成本高效的状况下,给用户提供最好的用户体验。
随机
开始,在原始产品中使用相同的调度方法。这个方法(在Docker Swarm存在以前)没有以任何方式限制容器,只是简单地随机选择一个服务器。
然而,运行全栈环境和运行代码段是完全不同的事——我们很快看到,这个解决方案不理想。我们的服务器经常因繁忙导致CPU过载和内存不足。
硬限制
我们一起根据需要定义了一个新的调度器。我们知道不能再随机选择服务器;我们需要的东西,可以限制资源,理想情况下,是很容易部署的。
幸运的是,Docker Swarm拥有全部这些品质,并且最近准备发布了。我们使用扩展调度策略,以减少服务器故障中丢失的容器数量。我们还设置了基于镜像的相似关系,相似的容器可以运行在同样的盒子里。
我们用Datadog的Docker intergration来更详细地看我们的容器如何使用资源。Datadog包括所有我们需要的数据,用来描述每个容器的RAM/CPU使用率和每个服务器的磁盘使用率。
使用这个数据,我们发现内存是限制因素(不是CPU或磁盘),因此,我们决定用硬内存限制来调度我们的容器。我们看Datalog的内存分配,设置我们的硬限制在99个百分点,在1GB。我们还可以手动重写这个基于每个容器的限制。
这个方法非常好!我们不再看到我们的服务器内存不足,或因超载而运行缓慢。
软限制
享受由这个新发现带来的稳定性一段时间后,我们注意到,我们在服务器上预留了非常大量的资源。大多数容器实际的内存使用率远远低于我们硬限制的1GB。这意味着我们付出的比实际使用的多很多。
我们想要更有效率,又不损失稳定性。降低硬限制不是一个选项,因为需要内存的应用会因为这个限制而崩溃。
我们需要一种基于估计的限制,在必要时又可以被超越的调度方法。值得庆幸的是,Docker提供了一个内存预留选项来设置软内存限制。当设置软限制时,容器可以自由地使用和它需要的一样多的内存,但是,当服务器上有内存争用时,Docker会试图缩减内存回到软限制值。基于软限制的调度会减少我们的浪费,并设置一个硬限制来阻止失控。然而,Swarm没有这个功能,所以是需要我们使用GO语言的时候了。我们划分Swarm建立定制版本,调度内存预留,而不是硬限制内存。再次使用Datadog收集的数据,我们基于概率选择理想的软限制,并设置硬限制到我们见过容器使用的最大值。这个方法显著地减少了浪费,而且没有影响到稳定。
动态范围和超越
在Docker1.12.0版中,最酷的一个功能之一是调度软限制的能力。虽然它仍等待发布,我们已经提前尝试了它,可以简便地用docker service create --reserve-memory <SOFT_LIMIT>
来使用软限制调度。
鉴于软内存限制的成功,我们的下一步是为每个容器动态地选择软限制和硬限制。因为所有的数据都输送到了Datadog,我们可以运行一个查询,得到理想的软硬限制,来保持容器稳定运行而不浪费资源。敬请关注这个博客,我们一有结果就会让您知道!
评论前必须登录!
注册