项目中在使用hpa来弹性扩缩pod,使用到了hpa的behavior字段,去查询了该字段的用法,在使用中发现与预期的结果不一致,这里记录一下问题及理解。

官方的link

​​​​​​Pod 水平自动扩缩 | KubernetesPod 水平自动扩缩(Horizontal Pod Autoscaler) 可以基于 CPU 利用率自动扩缩 ReplicationController、Deployment、ReplicaSet 和 StatefulSet 中的 Pod 数量。 除了 CPU 利用率,也可以基于其他应程序提供的 自定义度量指标 来执行自动扩缩。 Pod 自动扩缩不适用于无法扩缩的对象,比如 DaemonSet。Pod 水平自动扩缩特性由 Kubernetes API 资源和控制器实现。资源决定了控制器的行为。 控制器会周期性地调整副本控制器或 Deployment 中的副本数量,以使得类似 Pod 平均 CPU 利用率、平均内存利用率这类观测到的度量值与用户所设定的目标值匹配。Pod 水平自动扩缩工作机制 Pod 水平自动扩缩器的实现是一个控制回路,由控制器管理器的 --horizontal-pod-autoscaler-sync-period 参数指定周期(默认值为 15 秒)。每个周期内,控制器管理器根据每个 HorizontalPodAutoscaler 定义中指定的指标查询资源利用率。 控制器管理器可以从资源度量指标 API(按 Pod 统计的资源用量)和自定义度量指标 API(其他指标)获取度量值。 对于按 Pod 统计的资源指标(如 CPU),控制器从资源指标 API 中获取每一个 HorizontalPodAutoscaler 指定的 Pod 的度量值,如果设置了目标使用率, 控制器获取每个 Pod 中的容器资源使用情况,并计算资源使用率。 如果设置了 target 值,将直接使用原始数据(不再计算百分比)。 接下来,控制器根据平均的资源使用率或原始值计算出扩缩的比例,进而计算出目标副本数。需要注意的是,如果 Pod 某些容器不支持资源采集,那么控制器将不会使用该 Pod 的 CPU 使用率。 下面的算法细节章节将会介绍详细的算法。icon-default.png?t=N7T8https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/

默认行为

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selectPolicy: Max

这里主要有几个字段,

stabilizationWindowSeconds:当指标显示目标应该缩容时,自动扩缩算法查看之前计算的期望状态,并使用指定时间间隔内的最大值。就是说会在过去5分钟内选择期望值最高的一个值,是为了防止副本数抖动的过于频繁。

periodSeconds:在该时间内,副本数变化最多不会超过Percent或pods定义的数量。这个字段我之前的理解是两次扩缩容之间的间隔,其实并不是,你在实际操作的 时候会发现不管该值设置大小,扩缩容的时间间隔不会是你设置的这个值。这个值是限制单位时间内副本可变化的数量的。比如如下配置:

behavior:
    scaleDown:
      policies:
      - type: Pods
        value: 1
        periodSeconds: 180
      stabilizationWindowSeconds: 0
      #selectPolicy: Disabled
    scaleUp:
      policies:
      - type: Pods
        value: 2
        periodSeconds: 300
      #- type: Pods
        #alue: 4
        #eriodSeconds: 15
      selectPolicy: Max
      stabilizationWindowSeconds: 0

上面脚本定义了扩容时5分钟内最多扩2个,缩容时3分钟内最多缩一个,用kubectl describe hpa看下结果 

初始副本数是3个,压测开始,先是第一次25m时候扩容到4个,后面一分钟24m又进行一次扩容到5个,此时压力不减,仍然是超出target值的,但是后面几分钟并没有再次扩容,直到20m的时候再次进行扩容到6,然后7,可见在25m-20m之间,只扩容了2个副本。这与我们定义的扩容策略是一致的。

其后再看缩容情况,压测结束9m38s开始缩容,可以看到从7副本缩容到3副本,之间每次缩容的间隔时间是3分钟,也是符合了定义的缩容策略

结合扩缩容的实际数据,periodSeconds的时间可以理解了,它只是限制在单位时间内扩缩最多的副本大小,并不是控制两次扩缩容的时间间隔(这个是我以前一直理解错误的,并且网络上的文章都是复制黏贴也没有详细的解释)。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐