首页 > 解决方案 > Kubernetes pod 获得不同的 CPU 限制

问题描述

我们在 Kubernetes 集群中有几个使用 Apache Ignite 的应用程序。Ignite 创建各种大小如下的线程池:

Math.max(8, Runtime.getRuntime().availableProcessors())

所以基本上线程池的大小总是至少为 8,但如果系统认为有更多的处理器,可能会更多。

我们遇到的问题是,一些 pod 使用 8 大小的池进行旋转,而其他 pod 使用 36 大小,这是节点上的 CPU 数量。

我们使用 Helm 部署所有应用程序,但我们没有为任何 pod 设置任何 CPU 限制。理论上,它们都应该看到相同数量的可用 CPU。

还有什么可能导致同一节点上的 pod 看到有多少可用处理器的不同视图?

更新

Runtime#availableProcessors()我们在所有应用程序中都有一个运行状况端点,它使用Ignite 使用的相同方法显示JVM 报告的 CPU 数量。

我们所有的应用程序,包括 Ignite 认为有 36 个 CPU 的应用程序,都会在进程开始后报告 2 个处理器。

我在该方法的 Java 文档中发现了这一有趣的行:

此值可能会在虚拟机的特定调用期间发生变化。因此,对可用处理器数量敏感的应用程序应偶尔轮询此属性并适当调整其资源使用情况。

似乎我们处于竞争状态,在应用程序启动的早期,该值报告为 36,但在某些时候下降到 2。根据 Ignite bean 的触发时间,它们看到的是 36 或 2。

标签: kuberneteskubernetes-helm

解决方案


tl; dr根本问题似乎是何时resources.requests.cpu准确设置为1000m.

我编写了一个简单的 Java 应用程序来转储可用的处理器数量:

public class CpuTest {
    public static void main(String[] args) {
        System.out.println("Number of CPUs = "
                            + Runtime.getRuntime().availableProcessors());   
    }
}

我打包成一个 Dockerfile 并创建了一个简单的部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cputest
  labels:
    app: cputest
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cputest
  template:
    metadata:
      labels:
        app: cputest
    spec:
      containers:
      - name: cputest
        image: dev/cputest:latest
        imagePullPolicy: Never

我在具有 24 个内核的本地 RedHat 7 机器上运行它。预期的输出:

Number of CPUs = 24

然后我将各种 CPU 资源请求应用于部署:

        resources:
          requests:
            cpu: 1000m

并重新部署。结果很有趣:

  • CPU 请求设置为 500m:应用报告 1 个 CPU
  • CPU 请求设置为 1000m:应用报告 24 CPU <==
  • CPU 请求设置为 1001m:应用报告 2 CPU
  • CPU 请求设置为 2000m:应用报告 2 CPU
  • CPU 请求设置为 4000m:应用报告 4 CPU

所以这个问题只有在设置 CPU 请求时才会出现1000m(也尝试过1并得到相同的结果,它认为它拥有所有 24 个 CPU)。

我回去查看了我们所有的应用程序。果然,我们将 CPU 请求设置为确切1000m的那些是有问题的。任何其他值都按预期工作。

有趣的是,当我也将 CPU 限制设置为1000m时,问题就消失了,JVM 报告了 1 个 CPU。

这很可能是意料之中的,我不完全理解 Kubernetes 是如何使用 CPU 资源和限制的,或者我们所使用的版本(1.12.7)可能存在问题。

无论哪种方式,我至少对为什么我们的一些 pod 看到不同的 CPU 有一个答案。


推荐阅读