oomichi / try-kubernetes

11 stars 5 forks source link

Unused HPA configuration #130

Closed oomichi closed 1 year ago

oomichi commented 1 year ago

We sould be able to specify Utilization, Value and AverageValue for MetricTarget, but we can specify AverageValue only.

oomichi commented 1 year ago

The code: pkg/apis/autoscaling/types.go

328 // MetricTarget defines the target value, average value, or average utilization of a specific metric
329 type MetricTarget struct {
330         // Type represents whether the metric type is Utilization, Value, or AverageValue
331         Type MetricTargetType
332         // Value is the target value of the metric (as a quantity).
333         Value *resource.Quantity
334         // TargetAverageValue is the target value of the average of the
335         // metric across all relevant pods (as a quantity)
336         AverageValue *resource.Quantity
337 
338         // AverageUtilization is the target value of the average of the
339         // resource metric across all relevant pods, represented as a percentage of
340         // the requested value of the resource for the pods.
341         // Currently only valid for Resource metric source type
342         AverageUtilization *int32
343 }
344 
345 // MetricTargetType specifies the type of metric being targeted, and should be either
346 // "Value", "AverageValue", or "Utilization"
347 type MetricTargetType string
348 
349 const (
350         // UtilizationMetricType is a possible value for MetricTarget.Type.
351         UtilizationMetricType MetricTargetType = "Utilization"
352         // ValueMetricType is a possible value for MetricTarget.Type.
353         ValueMetricType MetricTargetType = "Value"
354         // AverageValueMetricType is a possible value for MetricTarget.Type.
355         AverageValueMetricType MetricTargetType = "AverageValue"
356 )
oomichi commented 1 year ago

k/k issue 79272 の概要

autoscaling v2 API ではユーザに Value もしくは AverageValue を指定することを許可している。 そのAPIにおいて、その二つの違いは Pods 数によってメトリックの値が割り算されるかどうかだけだ。 しかし実装面おいて、それとは少し異なる動作を行う。

Value

Value が与えられた場合、レプリカ数は GetObjectMetricReplicas もしくは GetExternalMetricReplicas 関数によって計算される。 それらの関数では target value によってメトリック値が割り算されることによって usage ratio が計算される。 そして、現在 Ready な Pod 数を usage ratio によって掛け算することによって、必要となるレプリカ数が決定される。

usageRatio := float64(utilization) / float64(targetUtilization) 
replicaCount = int32(math.Ceil(usageRatio * float64(readyPodCount))) 

AverageValue

AverageValue が与えられた場合、レプリカ数は GetObjectPerPodMetricReplicas もしくは GetExternalPerPodMetricReplicas 関数によって計算される。 それらの関数では、最初に target value を Pod 数で掛け算し、そして metric value を割り算する。 これは想定どおりだ。

しかし、必要となるレプリカ数を計算する際、usage ratio もしくは現在のPod 数は考慮に入れない。 そのかわり、PerPod 関数内で target value のみによってメトリック値を割り算するだけだ。

replicaCount = int32(math.Ceil(float64(utilization) / float64(targetAverageUtilization))) 

Feedback loop or not

Value を指定することでユーザはメトリックにおける特定の値を(オートスケールの)ターゲットにできる。 オートスケーラーは feedback loop を実装しており、指定した値になるように Pod 数を増やそうとする。 これにより、Pod 数を増やすことになる。もしもメトリック値が指定した値にならない場合、Pod 数をさらに増やそうとする。

しかしながら AverageValue を指定することでユーザはメトリック値をそれぞれの Pod にアサインし pinning する。 feedback loop は作られない。オートスケーラーは Pod 毎のメトリック値が指定した値になるよう Pod 数を reconcile する。

この振る舞い上の違いは微細であり、ドキュメントに記載されていない。

Why this behavior

この振る舞いは仕様だ。なぜならば大半の例では Pod 毎の理想的なメッセージが指定されている。

例えばあなたのアプリケーションが hosted queue service からタスクを進める場合、あなたは以下のセクションをあなたの HPA 設定マニュフェストに追加することで、1つの worker あたり30のタスクをやらせることができる。

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-metrics-not-related-to-kubernetes-objects

Documentation request

公式ドキュメント、types に関するコメント、そして実装においてこの振る舞い上の違いを明確に記載するべきだ。 AverageValue は feedback loop による良くできた実装になる可能性がある。 現状、feedback loop によって実装されていないことを説明すべきだろう。

oomichi commented 1 year ago

元々の疑問

HPA 設定において下記の設定は成功

type: AverageValue
averageValue: 500m

しかし下記は失敗

type: Utilization
averageUtilization: 50

エラーメッセージは「Required value: must specify a positive target averageValue」

oomichi commented 1 year ago

上記のエラーメッセージは HPA マニフェストで spec.Pods を指定したときに実行されるチェックで出力されるもの。

https://github.com/kubernetes/kubernetes/blob/742316ee2136b24b9edb0bb0d5bf69a6bad6f364/pkg/apis/autoscaling/validation/validation.go#L273

一方、公式ドキュメントの type: Utilization のサンプルでは spec.Pods は含まれていない。 まずは使用中の HPA マニフェストの内容を確認の上、spec.Pods の部分が削除可能か検討する。 https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics

oomichi commented 1 year ago

元々の疑問については、マニフェストの書き方が間違えていただけに見える。