这个方法和上面的方法有些类似,不过是根据behavior具体行为来做一个约束。如果是scaleUp,那么需要调用calculateScaleUpLimitWithScalingRules来获取预期扩容的pod数量,calculateScaleUpLimitWithScalingRules方法里面会根据behavior设置的selectPolicy以及scaleUp.type参数来做一个计算,如下:
func calculateScaleUpLimitWithScalingRules(currentReplicas int32, scaleEvents []timestampedScaleEvent, scalingRules *autoscalingv2.HPAScalingRules) int32 { var result int32 var proposed int32 var selectPolicyFn func(int32, int32) int32 if *scalingRules.SelectPolicy == autoscalingv2.DisabledPolicySelect { return currentReplicas // Scaling is disabled } else if *scalingRules.SelectPolicy == autoscalingv2.MinPolicySelect { selectPolicyFn = min // For scaling up, the lowest change ('min' policy) produces a minimum value } else { selectPolicyFn = max // Use the default policy otherwise to produce a highest possible change } for _, policy := range scalingRules.Policies { //获取最近变更的副本数 replicasAddedInCurrentPeriod := getReplicasChangePerPeriod(policy.PeriodSeconds, scaleEvents) periodStartReplicas := currentReplicas - replicasAddedInCurrentPeriod //根据不同的policy类型,决定不同的预期值 if policy.Type == autoscalingv2.PodsScalingPolicy { proposed = int32(periodStartReplicas + policy.Value) } else if policy.Type == autoscalingv2.PercentScalingPolicy { proposed = int32(math.Ceil(float64(periodStartReplicas) * (1 + float64(policy.Value)/100))) } result = selectPolicyFn(result, proposed) } return result } func getReplicasChangePerPeriod(periodSeconds int32, scaleEvents []timestampedScaleEvent) int32 { period := time.Second * time.Duration(periodSeconds) cutoff := time.Now().Add(-period) var replicas int32 //遍历最近变更 for _, rec := range scaleEvents { if rec.timestamp.After(cutoff) { // 更新副本修改的数量, 会有正负,最终replicas就是最近变更的数量 replicas += rec.replicaChange } } return replicas }如果没有设置selectPolicy那么selectPolicyFn默认就是max方法,然后在遍历Policies的时候,如果type是pod,那么就加上一个具体值,如果是Percent,那么就加上一个百分比。
如果当前的副本数已经大于scaleUpLimit,那么则设置scaleUpLimit为当前副本数,如果期望副本数超过了最大允许副本数,那么直接返回,否则返回期望副本数就好了。
下面来一张图理一下逻辑:
总结水平扩展大体逻辑可以用下面这两张图来进行一个概括,如果感兴趣的话,其中有很多细微的逻辑还是需要参照文档和代码一起理解起来才会更加的好。
Referencehttps://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/custom-metrics-api.md