我们最近将生产环境切换到Kubernetes。我想对容器实施CPU限制。我遇到了不一致的CPU指标。这是我的设置:


作为Daemonset运行的DataDog代理

没有CPU限制运行的现有应用程序
有问题的容器是多线程Ruby应用程序
两个度量标准:kubernetes.cpu.usage.{avg,max}docker.cpu.usage


c4.xlarge群集节点(以Kubernetes术语为4个vCPU或4000m)

kubernetes.cpu.usage.max报告有问题的容器的〜600m 。 docker.cpu.usage报告〜60%。因此,在正常操作下1000m CPU限制将绰绰有余。

我将限制设置为1000m。然后,docker.container.throttles显着上升,而kubernetes.cpu.usage.maxdocker.cpu.usage保持不变。在此期间,系统全都屈服了。这对我来说没有意义。

我研究了Docker统计信息。似乎docker stats(和底层API)根据CPU内核标准化了负载。因此,以Kubernetes而言,在60%的docker.cpu.usage(4000m * 0.60)到2400m之间。但是,这与任何Kubernetes编号都不相关。我做了另一个实验,以检验我的Kubernetes数不正确的假设。我将限制设置为2600m(有一些额外的净空)。这没有导致任何节流。但是Kubernetes观察到CPU使用率没有变化。这让我感到困惑。

所以我的问题是:


这听起来像Kubernetes中的错误(或堆栈中的东西吗?)
我的理解正确吗?

我的后续问题与如何正确确定Ruby应用程序的CPU有关。一个容器使用彪马。这是一个具有可配置线程数量的多线程Web服务器。 HTTP请求由线程之一处理。第二个应用程序是使用线程服务器的节俭服务器。每个传入的TCP连接均由其自己的线程处理。连接关闭时线程退出。 Ruby作为GIL(全局解释器锁),因此一次只能有一个线程可以执行Ruby代码。这确实允许多个线程执行IO等操作。

我认为最好的方法是限制每个应用程序中运行的线程数,并根据线程数近似估算Kubernetes CPU的限制。进程不是分叉的,因此很难预测CPU的总使用量。

这里的问题是:如何正确预测这些应用程序的CPU使用率和限制?

评论

您是否尝试过在1cpu节点和2cpu节点上查看数字之间的相关性(或不相关)?

#1 楼

这里有很多事情:


您使用的是AWS ec2,因此,您在实例上进行的用于测量CPU的工作都是在虚拟机管理程序级别而非实例级别上计算CPU。为此,请运行任何负载测试并检查iostat -ct 1和cloudwatch中的CPU使用率。 cloudwatch中的CPU使用率始终比iostat所报告的要高10-20%,这是因为iostat可以在虚拟机管理程序级别上提供CPU使用率。
作为Docker来了解kubernetes和docker指标的比较,我建议使用--cpuset = 1或任何数字以允许所有容器仅使用一个vCPU。
在AWS 1 CPU = 2vcpu中也是如此。它是2的超线程。您可以在计算时考虑到这一点。
最后,用于查看特定应用程序的CPU使用率的最佳指标是使用htop并与您的cloudwatch指标相关联。
他还观察到有时docker守护程序会将自己固定到其中一个虚拟CPU,因此当将其减少到1000m时,整个设置可能会变慢,因为任何vpcus上都在进行减少。您可以使用mpstat来了解此细节。
最后,在主机级别上,您可以将docker固定到单个CPU并观察更多。

希望这可以使您更加接近。如果您已找到解决方案,请更新我。