日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hpa原理详解

發布時間:2024/3/12 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hpa原理详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 1. hpa介紹

    • 1.1 hpa是什么

    • 1.2 hpa如何用起來

  • 2. hpa 源碼分析

    • 2.1 啟動參數介紹

    • 2.2 啟動流程

    • 2.3 核心計算邏輯

    • 2.4 計算期望副本數量

      • 2.4.1 GetRawMetric-具體的metric值

      • 2.4.2 calcPlainMetricReplicas-計算期望副本值

  • 3. 舉例說明計算過程

    • 3.1 hpa擴容計算邏輯

    • 3.2 場景1

    • 3.3 場景2

  • 4. 總結

本章重點: 從源碼角度分析hpa的計算邏輯

1. hpa介紹

1.1 hpa是什么

hpa指的是 Pod 水平自動擴縮,全名是Horizontal Pod Autoscaler簡稱HPA。它可以基于 CPU 利用率或其他指標自動擴縮 ReplicationController、Deployment 和 ReplicaSet 中的 Pod 數量。

用處: 用戶可以通過設置hpa,實現deploy pod數量的自動擴縮容。比如流量大的時候,pod數量多一些。流量小的時候,Pod數量降下來,避免資源浪費。

1.2 hpa如何用起來

(1)需要一個deploy/svc等,可以參考社區

(2)需要對應的hpa

舉例:

(1) 創建1個deploy。這里只有1個副本

apiVersion: apps/v1 kind: Deployment metadata:labels:app: zx-hpa-testname: zx-hpa spec:strategy:type: RollingUpdaterollingUpdate:maxSurge: 1replicas: 2selector:matchLabels:app: zx-hpa-testtemplate:metadata:labels:app: zx-hpa-testname: zx-hpa-testspec:terminationGracePeriodSeconds: 5containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- sleep- "3600"

(2)創建對應的hpa。

apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata:name: nginx-hpa-zx-1annotations:metric-containerName: zx-hpa spec:scaleTargetRef:apiVersion: apps/v1 ? // 這里必須指定需要監控那個對象kind: Deploymentname: zx-hpaminReplicas: 1 ? ? ? ? // deploy最小的Pod數量maxReplicas: 3 ? ? ? ? // deploy最大的Pod數量metrics:- type: Podspods:metricName: pod_cpu_1mtargetAverageValue: 60

hpa是從同命名空間下,找對應的deploy。所以yaml中指定deploy的時候不要指定namespaces。這也就要求,hpa 和deploy必須在同一命名空間。

這里我使用的 pod_cpu_1m這個指標。這是一個自定義指標。接下來就是分析

創建好之后,觀察hpa,當deploy的cpu利用率變化時,deploy的副本會隨之改變。

2. hpa 源碼分析

2.1 啟動參數介紹

hpa controller隨controller manager的初始化而啟動,hpa controller將以下flag添加到controller manager的flag中,通過controller manager的CLI端暴露給用戶:

// AddFlags adds flags related to HPAController for controller manager to the specified FlagSet. func (o *HPAControllerOptions) AddFlags(fs *pflag.FlagSet) {if o == nil {return} ?fs.DurationVar(&o.HorizontalPodAutoscalerSyncPeriod.Duration, "horizontal-pod-autoscaler-sync-period", o.HorizontalPodAutoscalerSyncPeriod.Duration, "The period for syncing the number of pods in horizontal pod autoscaler.")fs.DurationVar(&o.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration, "horizontal-pod-autoscaler-upscale-delay", o.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration, "The period since last upscale, before another upscale can be performed in horizontal pod autoscaler.")fs.MarkDeprecated("horizontal-pod-autoscaler-upscale-delay", "This flag is currently no-op and will be deleted.")fs.DurationVar(&o.HorizontalPodAutoscalerDownscaleStabilizationWindow.Duration, "horizontal-pod-autoscaler-downscale-stabilization", o.HorizontalPodAutoscalerDownscaleStabilizationWindow.Duration, "The period for which autoscaler will look backwards and not scale down below any recommendation it made during that period.")fs.DurationVar(&o.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration, "horizontal-pod-autoscaler-downscale-delay", o.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration, "The period since last downscale, before another downscale can be performed in horizontal pod autoscaler.")fs.MarkDeprecated("horizontal-pod-autoscaler-downscale-delay", "This flag is currently no-op and will be deleted.")fs.Float64Var(&o.HorizontalPodAutoscalerTolerance, "horizontal-pod-autoscaler-tolerance", o.HorizontalPodAutoscalerTolerance, "The minimum change (from 1.0) in the desired-to-actual metrics ratio for the horizontal pod autoscaler to consider scaling.")fs.BoolVar(&o.HorizontalPodAutoscalerUseRESTClients, "horizontal-pod-autoscaler-use-rest-clients", o.HorizontalPodAutoscalerUseRESTClients, "If set to true, causes the horizontal pod autoscaler controller to use REST clients through the kube-aggregator, instead of using the legacy metrics client through the API server proxy. This is required for custom metrics support in the horizontal pod autoscaler.")fs.DurationVar(&o.HorizontalPodAutoscalerCPUInitializationPeriod.Duration, "horizontal-pod-autoscaler-cpu-initialization-period", o.HorizontalPodAutoscalerCPUInitializationPeriod.Duration, "The period after pod start when CPU samples might be skipped.")fs.MarkDeprecated("horizontal-pod-autoscaler-use-rest-clients", "Heapster is no longer supported as a source for Horizontal Pod Autoscaler metrics.")fs.DurationVar(&o.HorizontalPodAutoscalerInitialReadinessDelay.Duration, "horizontal-pod-autoscaler-initial-readiness-delay", o.HorizontalPodAutoscalerInitialReadinessDelay.Duration, "The period after pod start during which readiness changes will be treated as initial readiness.") } 參數默認說明
horizontal-pod-autoscaler-sync-period15scontroller同步HPA信息的同步周期
horizontal-pod-autoscaler-downscale-stabilization5m縮容穩定窗口,縮容間隔時間(v1.12支持)
horizontal-pod-autoscaler-tolerance0.1最小縮放容忍度:計算出的期望值和實際值的比率<最小容忍比率,則不進行擴縮容
horizontal-pod-autoscaler-cpu-initialization-period5mpod剛啟動時,一定時間內的CPU使用率數據不參與計算。
horizontal-pod-autoscaler-initial-readiness-delay30s擴容等待pod ready的時間(無法得知pod何時就緒)

kcm中需要設置這個,才能啟動自定義的rest-clients。 –horizontal-pod-autoscaler-use-rest-clients=true

2.2 啟動流程

代碼流程:

startHPAControllerWithMetricsClient -> startHPAControllerWithMetricsClient -> Run -> worker -> processNextWorkItem -> reconcileKey->reconcileAutoscaler

func (a *HorizontalController) reconcileKey(key string) (deleted bool, err error) {namespace, name, err := cache.SplitMetaNamespaceKey(key)if err != nil {return true, err} ?hpa, err := a.hpaLister.HorizontalPodAutoscalers(namespace).Get(name)if errors.IsNotFound(err) {klog.Infof("Horizontal Pod Autoscaler %s has been deleted in %s", name, namespace)delete(a.recommendations, key)return true, nil} ?return false, a.reconcileAutoscaler(hpa, key) }

2.3 核心計算邏輯

metric的定義類型分為3種,resource、pods和external,這里只分析pods類型的metric。

reconcileAutoscaler函數就是hpa的核心函數。該函數主要邏輯如下:

  • 1.做一些類型轉換,用于接下來的Hpa計算

  • 2.計算hpa 的期望副本數量。

  • 3.根據計算的結果判斷是否需要改變副本數,需要改變的話,調用接口修改,然后做錯誤處理。

func (a *HorizontalController) reconcileAutoscaler(hpav1Shared *autoscalingv1.HorizontalPodAutoscaler, key string) error {// 1. 調用client向apiserver發送請求,scale是返回的hpa實體,然后做各種數據類型轉換,然后通過一個client向apiserver獲取scale,以及當然還有一些backup、把錯誤寫入hpa event的操作 。。。。代碼省略 ? // 2. 判斷是否需要計算副本數,如果需要,就調用computeReplicasForMetrics函數計算當前hpa的副本數。desiredReplicas := int32(0)rescaleReason := "" ?var minReplicas int32 ?if hpa.Spec.MinReplicas != nil {minReplicas = *hpa.Spec.MinReplicas} else {// Default valueminReplicas = 1} ?rescale := true ?if scale.Spec.Replicas == 0 && minReplicas != 0 {// Autoscaling is disabled for this resourcedesiredReplicas = 0rescale = falsesetCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "ScalingDisabled", "scaling is disabled since the replica count of the target is zero")} else if currentReplicas > hpa.Spec.MaxReplicas {rescaleReason = "Current number of replicas above Spec.MaxReplicas"desiredReplicas = hpa.Spec.MaxReplicas} else if currentReplicas < minReplicas {rescaleReason = "Current number of replicas below Spec.MinReplicas"desiredReplicas = minReplicas} else {var metricTimestamp time.TimemetricDesiredReplicas, metricName, metricStatuses, metricTimestamp, err = a.computeReplicasForMetrics(hpa, scale, hpa.Spec.Metrics)if err != nil {a.setCurrentReplicasInStatus(hpa, currentReplicas)if err := a.updateStatusIfNeeded(hpaStatusOriginal, hpa); err != nil {utilruntime.HandleError(err)}a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedComputeMetricsReplicas", err.Error())return fmt.Errorf("failed to compute desired number of replicas based on listed metrics for %s: %v", reference, err)} ?klog.V(4).Infof("proposing %v desired replicas (based on %s from %s) for %s", metricDesiredReplicas, metricName, metricTimestamp, reference) ?rescaleMetric := ""if metricDesiredReplicas > desiredReplicas {desiredReplicas = metricDesiredReplicasrescaleMetric = metricName}if desiredReplicas > currentReplicas {rescaleReason = fmt.Sprintf("%s above target", rescaleMetric)}if desiredReplicas < currentReplicas {rescaleReason = "All metrics below target"}desiredReplicas = a.normalizeDesiredReplicas(hpa, key, currentReplicas, desiredReplicas, minReplicas)rescale = desiredReplicas != currentReplicas}// 3.進行擴縮容,并進行錯誤處理。if rescale {scale.Spec.Replicas = desiredReplicas_, err = a.scaleNamespacer.Scales(hpa.Namespace).Update(targetGR, scale)if err != nil {a.eventRecorder.Eventf(hpa, v1.EventTypeWarning, "FailedRescale", "New size: %d; reason: %s; error: %v", desiredReplicas, rescaleReason, err.Error())setCondition(hpa, autoscalingv2.AbleToScale, v1.ConditionFalse, "FailedUpdateScale", "the HPA controller was unable to update the target scale: %v", err)a.setCurrentReplicasInStatus(hpa, currentReplicas)if err := a.updateStatusIfNeeded(hpaStatusOriginal, hpa); err != nil {utilruntime.HandleError(err)}return fmt.Errorf("failed to rescale %s: %v", reference, err)}setCondition(hpa, autoscalingv2.AbleToScale, v1.ConditionTrue, "SucceededRescale", "the HPA controller was able to update the target scale to %d", desiredReplicas)a.eventRecorder.Eventf(hpa, v1.EventTypeNormal, "SuccessfulRescale", "New size: %d; reason: %s", desiredReplicas, rescaleReason)klog.Infof("Successful rescale of %s, old size: %d, new size: %d, reason: %s",hpa.Name, currentReplicas, desiredReplicas, rescaleReason)} else {klog.V(4).Infof("decided not to scale %s to %v (last scale time was %s)", reference, desiredReplicas, hpa.Status.LastScaleTime)desiredReplicas = currentReplicas} ?a.setStatus(hpa, currentReplicas, desiredReplicas, metricStatuses, rescale)return a.updateStatusIfNeeded(hpaStatusOriginal, hpa) }

這里主要關心第二個步驟:hpa如何計算期望副本數量

2.4 計算期望副本數量

概念:

最小值:minReplicas。 這個是用戶在hpa里面的yaml設置的。這個是可選的,如果不設置,默認是1。

最大值:MaxReplicas。 這個是用戶在hpa里面的yaml設置的。這個必填的,如果不設置,會報錯, 如下。

當前值:currentReplicas。這個是hpa獲得的當前deploy的副本數量。

期望值:desiredReplicas。 這個是hpa希望deploy的副本數量。

error: error validating "nginx-deployment-hpa-test.yaml": error validating data: ValidationError(HorizontalPodAutoscaler.spec): missing required field "maxReplicas" in io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec; if you choose to ignore these errors, turn validation off with --validate=false

計算邏輯分為兩部分,第一種情況是不需要算,就可以直接得出期望值。 第二種情況需要調用函數計算。

情況1:不需要計算

(1)當前值等于0。 期望值=0. 不擴容,

(2)當前值 > 最大值。 沒必要計算期望值。 期望值=最大值,需要擴縮容。

(3)當前值 < 最小值。 沒必要計算期望值。 期望值=最小值,需要擴縮容。

情況2: 最小值 <= 當前值 <= 最大值。 需要調用函數計算 期望值。

這里的調用鏈為 computeReplicasForMetrics -> computeReplicasForMetric -> GetMetricReplicas

這里computeReplicasForMetrics有一個需要注意的點就是。這里可以處理了多個metric的情況。例如:這里一個hpa有多個指標。

- type: Resourceresource:name: cpu# Utilization類型的目標值,Resource類型的指標只支持Utilization和AverageValue類型的目標值target:type: UtilizationaverageUtilization: 50# Pods類型的指標- type: Podspods:metric:name: packets-per-second# AverageValue類型的目標值,Pods指標類型下只支持AverageValue類型的目標值target:type: AverageValueaverageValue: 1k

這里hpa的邏輯是,誰最大取誰。例如, 通過cpu.Utilization hpa算出來應該需要 4個pod。 但是packets-per-second算出來需要5個。這個時候就已5個為準。見下面代碼:

// computeReplicasForMetrics computes the desired number of replicas for the metric specifications listed in the HPA, // returning the maximum of the computed replica counts, a description of the associated metric, and the statuses of // all metrics computed. func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler, scale *autoscalingv1.Scale,metricSpecs []autoscalingv2.MetricSpec) (replicas int32, metric string, statuses []autoscalingv2.MetricStatus, timestamp time.Time, err error) { ?for i, metricSpec := range metricSpecs {replicaCountProposal, metricNameProposal, timestampProposal, condition, err := a.computeReplicasForMetric(hpa, metricSpec, specReplicas, statusReplicas, selector, &statuses[i]) ?if err != nil {if invalidMetricsCount <= 0 {invalidMetricCondition = conditioninvalidMetricError = err}invalidMetricsCount++}if err == nil && (replicas == 0 || replicaCountProposal > replicas) {timestamp = timestampProposalreplicas = replicaCountProposalmetric = metricNameProposal}} ?// If all metrics are invalid return error and set condition on hpa based on first invalid metric.if invalidMetricsCount >= len(metricSpecs) {setCondition(hpa, invalidMetricCondition.Type, invalidMetricCondition.Status, invalidMetricCondition.Reason, invalidMetricCondition.Message)return 0, "", statuses, time.Time{}, fmt.Errorf("invalid metrics (%v invalid out of %v), first error is: %v", invalidMetricsCount, len(metricSpecs), invalidMetricError)}setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionTrue, "ValidMetricFound", "the HPA was able to successfully calculate a replica count from %s", metric)return replicas, metric, statuses, timestamp, nil }

針對具體某個metric指標。計算分為倆步:

(1)GetRawMetric函數: 得到 具體的metric值

(2)calcPlainMetricReplicas :計算期望副本值

這里需要注意一點就是targetUtilization進行了數據轉換。乘以了10^3。

// GetMetricReplicas calculates the desired replica count based on a target metric utilization // (as a milli-value) for pods matching the given selector in the given namespace, and the // current replica count func (c *ReplicaCalculator) GetMetricReplicas(currentReplicas int32, targetUtilization int64, metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {metrics, timestamp, err := c.metricsClient.GetRawMetric(metricName, namespace, selector, metricSelector)if err != nil {return 0, 0, time.Time{}, fmt.Errorf("unable to get metric %s: %v", metricName, err)} ?replicaCount, utilization, err = c.calcPlainMetricReplicas(metrics, currentReplicas, targetUtilization, namespace, selector, v1.ResourceName(""))return replicaCount, utilization, timestamp, err }

2.4.1 GetRawMetric-具體的metric值

// GetRawMetric gets the given metric (and an associated oldest timestamp) // for all pods matching the specified selector in the given namespace func (c *customMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error) {// 1.這里直接調用 GetForObjects,發送restful請求獲取數據metrics, err := c.client.NamespacedMetrics(namespace).GetForObjects(schema.GroupKind{Kind: "Pod"}, selector, metricName, metricSelector)if err != nil {return nil, time.Time{}, fmt.Errorf("unable to fetch metrics from custom metrics API: %v", err)} ?if len(metrics.Items) == 0 {return nil, time.Time{}, fmt.Errorf("no metrics returned from custom metrics API")}// 2. 對獲取的數據進行處理。這里看起來是乘以了 10^3res := make(PodMetricsInfo, len(metrics.Items))for _, m := range metrics.Items {window := metricServerDefaultMetricWindowif m.WindowSeconds != nil {window = time.Duration(*m.WindowSeconds) * time.Second}res[m.DescribedObject.Name] = PodMetric{Timestamp: m.Timestamp.Time,Window: ? window,Value: ? ? int64(m.Value.MilliValue()),} ?m.Value.MilliValue()} ?timestamp := metrics.Items[0].Timestamp.Time ?return res, timestamp, nil }

2.4.2 calcPlainMetricReplicas-計算期望副本值

這里代碼省略,直接貼邏輯。

3.1 先從apiserver端拿到所有相關的pod,將這些pod分為三類:

a.missingPods用于記錄處于running狀態,但不提供該metric的pod ? b.ignoredPods 用于處理resource類型cpu相關metric的延遲(就是pod未就緒),這里不深入討論 ? c.readyPodCount記錄狀態為running,且能提供該metric的pod

3.2 調用GetMetricUtilizationRatio計算實際值與期望值的對比情況。計算時,對于所有可獲取到metric的pod,取它們metric value的平均值得到:usageRatio=實際值/期望值;utilization=實際值(平均)

3.3 計算期望pod數量DesiredReplicas。對于missingPods為0,即所有target pod都處于running可獲取metric value的情況:

a.如果實際值與期望值的對比usageRatio處于可容忍范圍內,不執行scale操作。默認情況下c.tolerance=0.1,即usageRatio處于

[0.9,1.1]時pod數量不變化

if math.Abs(1.0-usageRatio) <= c.tolerance {// return the current replicas if the change would be too smallreturn currentReplicas, utilization, nil }

b.實際值與期望值的對比usageRatio不在可容忍范圍內,向上取整得到desiredReplicas return int32(math.Ceil(usageRatio * float64(readyPodCount))), utilization, nil

對于missingPods>0,即有target pod的metric value沒有獲取到的情況。 縮容時,對于找不到metric的pod,視為正好用了desired value

if usageRatio < 1.0 { // on a scale-down, treat missing pods as using 100% of the resource request for podName := range missingPods {metrics[podName] = metricsclient.PodMetric{Value: targetUtilization}} }

擴容時,對于找不到metric的pod,視為該pod對指定metric的使用量為0

for podName := range missingPods {metrics[podName] = metricsclient.PodMetric{Value: 0} }

經過上面的處理后,重新計算實際值與期望值的對比newUsageRatio。

在下面兩種情況下,不執行scale操作:新的實際值與期望值的對比newUsageRatio在容忍范圍內; 賦值處理前后,一個需要scale up,另一個需要scale down。

其它情況下,同樣地執行向上取整操作

if math.Abs(1.0-newUsageRatio) <= c.tolerance || (usageRatio < 1.0 && newUsageRatio > 1.0) || (usageRatio > 1.0 && newUsageRatio < 1.0) {// return the current replicas if the change would be too small,// or if the new usage ratio would cause a change in scale directionreturn currentReplicas, utilization, nil} return int32(math.Ceil(newUsageRatio * float64(len(metrics)))), utilization, nil

最后,Hpa將desiredReplicas寫到scale.Spec.Replicas,調用a.scaleNamespacer.Scales(hpa.Namespace).Update(targetGR, scale)向apiserver發送更新hpa的請求,對某個hpa的一輪更新操作就完成了。

3. 舉例說明計算過程

3.1 hpa擴容計算邏輯

關鍵概念:tolerance(hpa擴容容忍度), 默認為0.1。

Custom server: 自定義metric服務。這里是一個抽象,用于給hpa提供具體的metric值。Custom server具體可以是prometheus,或者其他的監控系統。下一篇文章會講如何將Custom server和hpa聯系起來。

3.2 場景1

當前有deployA, 運行著倆個pod, A1和A2。 deploy設置了hpa,指標是內存使用量,并且規定,當平均使用量大于60就要擴容。

hpa擴容計算步驟:

第一步: 往monitor-adaptor發送請求, 要求獲得deployA下所有pod的metric值。 這里收到了 A1=50; A2=100

第二步: 補全metric值,給獲取不到metric值的pod賦值。 這里hpa會查看集群狀態,發現deployA 下有倆個pod,A1,A2。并且這兩個pod的metric值都獲取到了。 這個時候就不用補全。(下面例子就介紹需要補全metric的情況)

第三步: 開始計算

(1)計算 平均pod metric值和 target的比例。也可以叫擴容比例系數

ratio = (A1+A2)/(2*target) = (50+100)/120 = 1.25

按理說不用再除target值,直接(50+100)/2=75,然后拿75和60比就行。 75比60大就應該擴容。

這里使用系數表示主要有倆個原因:

  • 有容忍度的概念,使用比例方便和計算是否超出了容忍度

  • 用于擴縮容計算

(2)判斷是否超過容忍度

這里 1.25-1 > 0.1(默認容忍度)。 因此這種情況是需要擴容的。

這里就體現了容忍度的作用。有了容忍度, 平均metric需要大于 66才會擴容(60*1.1)

(3)計算真正的副本數量

向上取整: 擴容比例系數*當前的副本數

這里就是: 1.25*2 = 2.5 , 取整后就是3。

3.3 場景2

和場景1不同在于:由于某件原因,導致 monitor-adaptor往hpa發送的時候,只有 A1=20。 A2的數據丟失。

?

?

hpa擴容計算步驟:

第一步: 往monitor-adaptor發送請求, 要求獲得deployA下所有pod的metric值。 這里收到了 A1=2;

第二步: 補全metric值,給獲取不到metric值的pod賦值。 這里hpa會查看集群狀態,發現deployA 下有倆個pod,A1,A2。但是這里發現只有A1的值,這個時候hpa就認為A2 有數據,但是獲取失敗。所以就會給A2自己賦值, 0/target。

賦值邏輯如下: 當 A1 > target的時候,A2=0; 當A1<= target的時候,賦值為 target。

這里由于 A1=2, 比target(60)小,所以最終hpa計算時:

A1=2; A2=60; target=60;

第三步: 開始計算

(1)計算 平均pod metric值和 target的比例。也可以叫擴容比例系數

ratio = (A1+A2)/(2*target) = (2+60)/120 = 0.517

(2)判斷是否超過容忍度

這里 1-0.517 > 0.1(默認容忍度)。 因此這種情況是需要縮容的。

(3)計算真正的副本數量

向上取整: 擴容比例系數*當前的副本數(這里就是metric數量,A1,A2)

對應就是: 0.517*2 = 1.034 , 取整后就是2。

4. 總結

(1)hpa可以設置多個metric。當有多個metric時,誰算出來的副本值最大,取誰的值

(2)針對具體的metric而言(這里是以pods這種為例),首先獲得用戶定義的hpa指標。比如最大值,最小值,閾值等。

這里有一個點在于。閾值乘以了1000用于計算。

(3)獲取metric的值,這里是使用了自定義rest服務。hpa只要發送rest請求,就有數據。這種情況非常適用于公司使用自己的監控數據做擴縮容。 注意:這里每個值也乘以了1000。這樣和閾值就是相互抵消了。

(4)利用公式計算期望值。 期望值*X <= 當前pod所有的metric值。X取小的正整數。具體邏輯可以看上文的計算過程。

總結

以上是生活随笔為你收集整理的hpa原理详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。