跳至内容

节点资源分配

Kubernetes 中的节点资源处理

Kubernetes 集群的一个经常被忽视的方面是,非 Pod 组件运行所需的资源,例如

  • 操作系统组件,例如 sshdudev 等。
  • Kubernetes 系统组件,例如 kubelet容器运行时(例如 containerd)、节点问题检测器journald 等。

在管理集群时,了解这些组件非常重要,因为如果关键的非 Pod 组件没有足够的资源,最终可能会导致集群非常不稳定。

了解节点资源

集群中的每个节点都有可用的资源,计划在该节点上运行的 Pod 可能会也可能不会为其设置资源请求或限制。Kubernetes 会将 Pod 调度到具有满足 Pod 指定要求的资源的节点上。从广义上讲,Pod 会被bin-packed 到节点上,尽力尝试以最少的节点利用尽可能多的可用资源。

      Node Capacity
---------------------------
|     kube-reserved       |
|-------------------------|
|     system-reserved     |
|-------------------------|
|    eviction-threshold   |
|-------------------------|
|                         |
|      allocatable        |
|   (available for pods)  |
|                         |
|                         |
---------------------------

节点资源可以分为 4 类(如上所示)

  • kube-reserved - 为 Kubernetes 系统守护程序保留资源。
  • system-reserved - 为操作系统组件保留资源。
  • eviction-threshold - 指定当节点资源降至保留值以下时会触发驱逐操作的限制。
  • allocatable - 当 kube-reservedsystem-reservedeviction-threshold 资源已考虑在内时,可用于调度 Pod 的剩余节点资源。

例如,对于一台只有 eviction-thresholds 设置为 --eviction-hard=memory.available<100Mi 的 30.5 GB、4 vCPUs 机器,我们将获得以下 CapacityAllocatable 资源

$ kubectl describe node/ip-xx-xx-xx-xxx.internal
...
Capacity:
 cpu:   4
 memory:  31402412Ki
 ...
Allocatable:
 cpu:   4
 memory:  31300012Ki
 ...

那么,可能出现什么问题?

调度程序确保对于每种资源类型,已调度的资源总和不超过可分配资源总和。但是,假设您在集群中部署了几个应用程序,它们不断使用远远超过其资源请求中设置的资源(在工作负载期间,突发量超过请求,但低于限制)。最终,您将拥有一个节点,其上的 Pod 每个都试图占用比该节点上可用资源更多的资源!

这对像内存这样的不可压缩资源来说尤其是一个问题。例如,在上述情况下,如果 eviction-threshold 仅为 memory.available<100Mi 并且没有设置 kube-reservedsystem-reserved 预留,则节点可能会在 kubelet 能够回收内存之前发生 OOM(因为它可能不会立即观察到内存压力,因为它会定期轮询 cAdvisor 收集内存使用情况统计信息)。

始终牢记,如果没有设置 kube-reservedsystem-reserved 预留(大多数集群都是如此,例如 GKEkOps),调度程序不会考虑非 Pod 组件正常运行所需的资源,因为 CapacityAllocatable 资源或多或少是相等的。

我们该怎么办?

很难为节点资源分配提供一个通用的答案。集群的行为取决于在集群上运行的应用程序的资源要求、Pod 密度和集群大小。但是,有一个节点性能仪表板 可以显示在多个 Pod 密度级别下 kubeletdocker 引擎的 cpumemory 使用情况配置文件,这可以作为您集群的适当值的指南。

但是,以下建议似乎很合适

  1. 始终设置留有余地的请求 - 不要将请求设置得太接近应用程序在空闲时间段内的资源配置文件。
  2. 始终设置限制 - 以便应用程序不会在峰值期间占用节点上的所有内存。
  3. 不要将不可压缩资源的限制设置得太高 - 归根结底,Kubernetes 调度程序是根据与节点上可用资源匹配的资源请求进行调度的。在峰值期间,您的 Pod 在技术上会尝试访问超出其保证可访问的资源范围的资源。如前所述,如果您的许多 Pod 同时出现突发,这可能会成为问题。
  4. 如果驱逐阈值过低,请提高它们 - 虽然极端利用率是理想的,但它可能太接近边缘,以至于如果资源在该窗口内迅速增加,系统可能没有足够的时间通过驱逐来回收资源。
  5. 在您能够分析节点(即 kube-reservedsystem-reserved)后,为系统组件保留资源。

进一步阅读