13.深入k8s:Pod 水平自动扩缩HPA及其源码分析 (4)

这里会根据不同的度量类型来进行统计,目前度量类型有四种,分别是Pods、Object、Resource、External,解释如下:

const ( // ObjectMetricSourceType is a metric describing a kubernetes object // (for example, hits-per-second on an Ingress object). // 这种度量专门用来描述k8s的内置对象 ObjectMetricSourceType MetricSourceType = "Object" // PodsMetricSourceType is a metric describing each pod in the current scale // target (for example, transactions-processed-per-second). The values // will be averaged together before being compared to the target value. // 这种度量描述在目前被统计的每个pod平均期望值 PodsMetricSourceType MetricSourceType = "Pods" // ResourceMetricSourceType is a resource metric known to Kubernetes, as // specified in requests and limits, describing each pod in the current // scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available // to normal per-pod metrics (the "pods" source). // Resource描述的是每个pod中资源,如CPU或内存 ResourceMetricSourceType MetricSourceType = "Resource" // ExternalMetricSourceType is a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster // (for example length of queue in cloud messaging service, or // QPS from loadbalancer running outside of cluster). // External类型表示的是一种全局的度量,和k8s对象无关,主要依赖外部集群提供信息 ExternalMetricSourceType MetricSourceType = "External" )

我们这里不会全部都介绍,挑选pod度量类型作为例子。pod这个分支会调用computeStatusForPodsMetric方法来计算需要扩缩容的数量。

computeStatusForPodsMetric&GetMetricReplicas:计算需要扩缩容的数量

文件位置:pkg/controller/podautoscaler/replica_calculator.go

func (a *HorizontalController) computeStatusForPodsMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (replicaCountProposal int32, timestampProposal time.Time, metricNameProposal string, condition autoscalingv2.HorizontalPodAutoscalerCondition, err error) { //计算需要扩缩容的数量 replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetMetricReplicas(currentReplicas, metricSpec.Pods.Target.AverageValue.MilliValue(), metricSpec.Pods.Metric.Name, hpa.Namespace, selector, metricSelector) if err != nil { condition = a.getUnableComputeReplicaCountCondition(hpa, "FailedGetPodsMetric", err) return 0, timestampProposal, "", condition, err } ... return replicaCountProposal, timestampProposal, fmt.Sprintf("pods metric %s", metricSpec.Pods.Metric.Name), autoscalingv2.HorizontalPodAutoscalerCondition{}, nil } 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) { //获取pod中度量数据 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 }

这里会调用GetRawMetric方法来获取pod对应的度量数据,然后再调用calcPlainMetricReplicas方法结合度量数据与目标期望来计算希望扩缩容的数量是多少。

calcPlainMetricReplicas:计算副本数具体实现

calcPlainMetricReplicas方法逻辑比较多,下面分开来讲解。

func (c *ReplicaCalculator) calcPlainMetricReplicas(metrics metricsclient.PodMetricsInfo, currentReplicas int32, targetUtilization int64, namespace string, selector labels.Selector, resource v1.ResourceName) (replicaCount int32, utilization int64, err error) { podList, err := c.podLister.Pods(namespace).List(selector) ... //将pod分成三类进行统计,得到ready的pod数量、ignored Pod集合、missing Pod集合 readyPodCount, ignoredPods, missingPods := groupPods(podList, metrics, resource, c.cpuInitializationPeriod, c.delayOfInitialReadinessStatus) //在度量的数据里移除ignored Pods集合的数据 removeMetricsForPods(metrics, ignoredPods) //计算pod中container request 设置的资源之和 requests, err := calculatePodRequests(podList, resource) ... }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypgss.html