我们最近将生产环境切换到Kubernetes。我想对容器实施CPU限制。我遇到了不一致的CPU指标冲突。这是我的设置:
- DataDog代理以
Daemonset
- 现有应用程序不受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.max
并docker.cpu.usage
保持不变。在此期间,系统全都屈服了。这对我来说没有意义。
我研究了Docker统计信息。似乎docker stats
(和底层API)根据CPU内核规范了负载。因此,以我的情况来说,docker.cpu.usage
以Kubernetes计,60%(4000m * 0.60)达到2400m。但是,这与任何Kubernetes编号都不相关。我做了另一个实验,以检验我的Kubernetes数不正确的假设。我将限制设置为2600m(以获得一些额外的净空)。这没有导致任何节流。但是Kubernetes观察到CPU使用率没有变化。这让我感到困惑。
所以我的问题是:
- 这是否感觉像Kubernetes中的错误(或堆栈中的某物?)
- 我的理解正确吗?
我的后续问题与如何正确确定Ruby应用程序的CPU有关。一个容器使用彪马。这是具有可配置线程数量的多线程Web服务器。HTTP请求由线程之一处理。第二个应用程序是使用线程服务器的节俭服务器。每个传入的TCP连接均由其自己的线程处理。连接关闭时线程退出。Ruby作为GIL(全局解释器锁),因此一次只能有一个线程执行Ruby代码。这确实允许多个线程执行IO之类的操作。
我认为最好的方法是限制每个应用程序中运行的线程数,并根据线程数近似计算Kubernetes CPU的限制。进程不是分叉的,因此很难预测CPU的总使用量。
这里的问题是:如何正确预测这些应用程序的CPU使用率和限制?