Kubernetes の HPA(HorizontalPodAutoscaler) の Utilization

kubernetes の HPA(HorizontalPodAutoscaler)の Utilization で指定する cpu 使用率、いわゆる論理1コアを 100 とするパーセンテージなのかと思っていたら違ったのでメモ。

例えば次のように設定されているとき、

# HorizontalPodAutoscaler
  ...snip...
  minReplicas: 1
  maxReplicas: 40
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80
  ...snip...
# Pod
  ...snip...
        resources:
          limits:
            cpu: 100m
          requests:
            cpu: 50m
  ...snip...

この状態でポッドで yes > /dev/null するとポッドのリソース制限値(resources.limits)が 100m = 0.1 = 10% なのでCPU使用率は 10% まであがります。

HorizontalPodAutoscaler の Utilization はポッドのリソース要求値(resources.requests)に対するパーセンテージのようなので、この設定だと 50m * 80% = 40m = 0.04 = 4% となり CPU 使用率(のポッドの平均)が 4% を超えただけでスケールアウトし、この例だとポッド数は 3 まで増えます。

以下計算式。

50 * 0.8 = 40 < 100 / 1 = 100
50 * 0.8 = 40 < 100 / 2 =  50
50 * 0.8 = 40 > 100 / 3 =  33.3333....

次のようにポッドの cpu の limits を削除するとCPU使用率は 100% まであがります。

# Pod
        resources:
          requests:
            cpu: 50m

このときポッド数は 22 まで増えました。単純計算で 25 まで増えると思いましたが、1000/22 は 45.454545... なのでだいたいそれぐらいなのでしょうか(ちょっと不可解)。

次に Pod の cpu の requests と 500m にしてみると、

# Pod
        resources:
          requests:
            cpu: 500m

スケールアウトの閾値が 400m = 0.4 = 40% となるのでポッド数は 3 までしか増えません。


ポッドではなくノードのオートスケールも要求量に対するキャパシティで行われるので(オートスケーラーの設定などによるもしれない・・そもそも Fargate だとどうなるのかとかは判らない)、2番目の例は1番目や3番目の例と比べて同じノードの多数のポッドが作られやすくなりそうです。

なお次のようにすれば絶対量でも指定できるようです(この例だとコアの50%)。

# HorizontalPodAutoscaler
  minReplicas: 1
  maxReplicas: 40
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: AverageValue
          averageUtilization: 500m