装箱调度(Binpack)是一种优化算法,以最小化资源使用量为目标,将资源合理地分配给每个任务,使所有资源都可以实现最大化的利用价值。在集群工作负载的调度过程中使用 Binpack 调度策略,调度器会优先将 Pod 调度到资源消耗较多的节点,减少各节点空闲资源碎片,提高集群资源利用率。

Binpack 功能介绍

Binpack 调度算法的目标是最大限度地填满现有节点,尽量避免将 Pod 调度至空闲节点。具体实现中,调度器会对所有满足条件的节点进行打分,资源利用率越高,得分越高,调度优先级也越高。Binpack 算法能够尽可能填满节点,将应用负载靠拢在部分节点,这非常有利于集群节点的自动扩缩容功能。

Binpack 为 Volcano 调度器的多个调度插件之一,与其他调度插件协同工作,共同影响节点的最终得分。用户可自定义 Binpack 插件的全局权重,并分别为 CPU、内存基础资源以及 GPU、NPU 等扩展资源配置打分权重,从而控制 Binpack 在调度决策中的影响程度。在计算 Binpack 得分时,调度器会综合考虑 Pod 所请求的各类资源,并基于各资源的打分权重进行加权平均,以确定节点的最终得分。

Binpack 算法原理

在对节点打分时,Binpack 会结合插件的全局权重和各资源维度(如 CPU、内存、GPU 等)的权重值,计算出节点 Binpack 得分。节点 Binpack 得分的计算流程如下:

首先,对 Pod 请求资源中的每类资源依次打分,以 CPU 为例,CPU 资源在待调度节点的得分信息如下:

CPU.weight * (request + used) / allocatable

CPU 权重值越高,得分越高,节点资源使用量越满,得分越高。Memory、GPU 等资源原理类似。其中:

  • CPU.weight 为用户设置的 CPU 权重

  • request 为当前 Pod 请求的 CPU 资源量

  • used 为当前节点已经分配使用的 CPU 量

  • allocatable 为当前节点 CPU 可用总量

通过 Binpack 策略的节点总得分如下:

binpack.weight * (CPU.score + Memory.score + GPU.score) / (CPU.weight+ Memory.weight+ GPU.weight) * 100

binpack 插件的权重值越大,得分越高,某类资源的权重越大,该资源在打分时的占比越大。其中:

  • binpack.weight 为用户设置的装箱调度策略权重

  • CPU.score 为 CPU 资源得分,CPU.weight 为 CPU 权重

  • Memory.score 为 Memory 资源得分,Memory.weight 为 Memory 权重

  • GPU.score 为 GPU 资源得分,GPU.weight 为 GPU 权重

binpack

如图所示,假设集群中存在两个节点,分别为 Node 1 和 Node 2,当前有一个 Pod 请求了 CPU、内存和 GPU 资源。在调度 Pod 时,Binpack 策略将对两个节点进行打分。

假设集群中 CPU.weight 配置为 1,Memory.weight 配置为 1,GPU.weight 配置为 2,binpack.weight 配置为 5。

  1. Binpack 对 Node 1 的打分信息如下:

    各资源按照公式计算得分,具体信息如下:

    • CPU Score:CPU.weight * (request + used) / allocatable = 1 * (2 + 4)/ 8 = 0.75

    • Memory Score:Memory.weight * (request + used) / allocatable = 1 * (4 + 8) / 16 = 0.75

    • GPU Score: GPU.weight * (request + used) / allocatable = 2 * (4 + 4)/ 8 = 2

    节点总得分按照 binpack.weight * (CPU.score + Memory.score + GPU.score) / (CPU.weight+ Memory.weight+ GPU.weight) * 100 公式进行计算,具体如下:

    假设 binpack.weight 配置为 5,Node 1 在 Binpack 策略下的得分:5 * (0.75 + 0.75 + 2)/(1 + 1 + 2)* 100 = 437.5

  2. Binpack 对 Node 2 的打分信息如下:

    • CPU Score:CPU.weight * (request + used) / allocatable = 1 * (2 + 6)/ 8 = 1

    • Memory Score:Memory.weight * (request + used) / allocatable = 1 * (4 + 8) / 16 = 0.75

    • GPU Score:GPU.weight * (request + used) / allocatable = 2 * (4 + 4)/ 8 = 2

    Node 2 在 Binpack 策略下的得分:5 * (1 + 0.75 + 2)/(1 + 1 + 2)* 100 = 468.75

综上,Node 2 得分大于 Node 1,按照 Binpack 策略,Pod 将会优先调度至 Node 2。

配置装箱调度策略

	   tiers:
	   - plugins:
	     - name: binpack
	       arguments:
	         binpack.weight: 10
	         binpack.cpu: 5
	         binpack.memory: 1
	         binpack.resources: nvidia.com/gpu, example.com/foo
	         binpack.resources.nvidia.com/gpu: 2
	         binpack.resources.example.com/foo: 3