K8S水平伸缩-HPA
HPA(Horizontal Pod Autoscaler)K8S的水平扩缩容其实也是由一个独立的控制器管理的, 也就是HPA。API 细节HPA 属于 autoscaling API 组的资源组kubectl api-versions | grep autoscalautoscaling/v1autoscaling/v2beta1autoscaling/v2beta2autoscaling/v1
HPA(Horizontal Pod Autoscaler)
K8S的水平扩缩容其实也是由一个独立的控制器管理的, 也就是HPA。
API 细节
HPA 属于 autoscaling API 组的资源组
kubectl api-versions | grep autoscal
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
- autoscaling/v1:只支持基于CPU指标的缩放。
- autoscaling/v2beta1:支持Resource Metrics(资源指标,如pod的CPU)和Custom Metrics(自定义指标)的缩放。
- autoscaling/v2beta2:支持Resource Metrics(资源指标,如pod的CPU)和Custom Metrics(自定义指标)和ExternalMetrics(额外指标)的缩放。
HPA 原理
HPA本质上也是个控制器,控制器本质上也是个不停循环的过程,HPA默认的循环间隔时间为15s(由参数–horizontal-pod-autoscaler-sync-period 控制)。每次循环会进行资源的检查(1.11 之后从metric-server 获取资源使用情况),对比HPA的资源使用限制,一旦触发伸缩条件,HPA会向kubernetes发送请求,修改伸缩对象(statefulSet, replicaController, replicaSet)子对象scale中控制pod数量的字段。kubernetess响应请求,修改scale结构体,然后会刷新一次伸缩对象的pod数量。伸缩对象被修改后,自然会通过list/watch机制增加或减少pod数量,达到动态伸缩的目的。
因为控制器的本质就是不停循环,然后将当前状态和期望状态进行对比,如果不满足期望状态,则触发对应动作。
HPA 扩容算法:
期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]
使用HPA 前置条件
- 必须部署metric server, 1.11 之前是从 Heapster 获取指标特性的,目前已废弃,远古版本不做考虑
- 资源控制器必须指定resources,且不能为{} (resources 资源使用为{} 可能会导致kubectl get hpa 返回unknown)
防抖动
HPA 控制器默认15s 检查一次, 如果监控数据频繁抖动,可能会导致短时间内pod副本数量变化过大,这其实不利用生产的额稳定,所以 kube-controller-manager 在启动的时候加上 --horizontal-pod-autoscaler-downscale-stabilization, 默认时间是 5 分钟(5m0s) 该时间表示距离上次扩缩容后,多久之后才能再扩缩容, 这也就是所谓的冷静期。
HPA YML 例子
apiVersion: autoscaling/v2beta2 # 版本 V1 默认只支持CPU,指标过于少,不太建议
kind: HorizontalPodAutoscaler
metadata:
name: nginx
namespace: default
spec:
# HPA的伸缩对象描述,HPA会动态修改该对象的pod数量
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
# HPA的最小pod数量和最大pod数量
minReplicas: 1
maxReplicas: 10
# 监控的指标数组,v2beta2 支持多种类型的指标共存
metrics:
# Object类型的指标
- type: Object
object:
metric:
# 指标名称
name: requests-per-second
# 监控指标的对象描述,指标数据来源于该对象
describedObject:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
# Value类型的目标值,Object类型的指标只支持Value和AverageValue类型的目标值
target:
type: Value
value: 10k
# Resource类型的指标
- type: Resource
resource:
name: cpu
# Utilization类型的目标值,Resource类型的指标只支持Utilization和AverageValue类型的目标值
target:
type: Utilization
averageUtilization: 50
# Pods类型的指标
- type: Pods
pods:
metric:
name: packets-per-second
# AverageValue类型的目标值,Pods指标类型下只支持AverageValue类型的目标值
target:
type: AverageValue
averageValue: 1k
# External类型的指标
- type: External
external:
metric:
name: queue_messages_ready
# 该字段与第三方的指标标签相关联,(此处官方文档有问题,正确的写法如下)
selector:
matchLabels:
env: "stage"
app: "myapp"
# External指标类型下只支持Value和AverageValue类型的目标值
target:
type: AverageValue
averageValue: 30
- target共有3种类型:Utilization, Value, AverageValue。
- Utilization表示平均使用率; Value表示裸值; AverageValue表示平均值。
- metrics中的type字段有四种类型的值:Object、Pods、Resource、External。
- Resource指的是当前伸缩对象下的pod的cpu和memory指标,只支持Utilization和AverageValue类型的目标值。
- Object指的是指定k8s内部对象的指标,数据需要第三方adapter提供,只支持Value和AverageValue类型的目标值。
- Pods指的是伸缩对象(statefulSet、replicaController、replicaSet)底下的Pods的指标,数据需要第三方的adapter提供,并且只允许AverageValue类型的目标值。
- External指的是k8s外部的指标,数据同样需要第三方的adapter提供,只支持Value和AverageValue类型的目标值。
自定义指标
- [ 等prometheus 系列写完再更新。 ]
个人公众号, 分享一些日常开发,运维工作中的日常以及一些学习感悟,欢迎大家互相学习,交流
更多推荐
所有评论(0)