K8s Pod水平自动扩缩(Aotuscaling)
【Kubernetes】Pod 之 扩容和缩容 - 掘金 (juejin.cn)
简介
在Kubernetes中,HorizontalPodAutoscaler自动更新工作负载资源(例如Deployment或者StatefulSet),目的是自动扩缩工作负载以满足需求。
水平扩缩意味着对增加的负载影响是部署更多的Pod。这与垂直(Vertical)扩缩不同,对于Kubernetes垂直扩缩意味着将更多的资源(例如CPU内存)分配给已经为工作负载运行的Pod。
如果负载减少,并且Pod的数量高于配置的最小值,HorizontalPodAutoscaler会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)缩减。
水平Pod自动缩扩不适用无法缩扩的对象例如DaemonSet
HorizontalPodAutoscaler 被实现为Kubernetes API资源和控制器。
资源决定了控制器的行为。在Kubernetes控制平面内运行的水平Pod自动扩缩容控制器会定期调整其目标(例如:Deployment)的所需规模,以及匹配观察到的目标,例如,平均CPI利用率,平均内存利用率,或你指定的任何其他自定义指标。
Pod 扩缩容分为两种模式,手动扩缩容和自动扩缩容:
- 手动扩缩容:通过执行命令
kubectl scale或通过RESTful API对Deployment/rc/rs进行Pod副本数量设置来一键完成扩缩容。 - 自动扩缩容:指定某个性能指标或自定义业务指标的范围,以及指定
Pod副本数量的范围,kubernetes系统会自动在副本数量的范围内根据性能指标的变化进行调整。

手动扩缩容
通过命令 kubectl scale 可以进行手动扩缩容,使用参数 --replicas 指定需要增加或是减少 Pod 的数量到某个指定的数字。
- 创建
nginx-deployment.yaml文件
yaml复制代码apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80- 执行创建
shell复制代码$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created- 查看
shell复制代码$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5754944d6c-hkz57 1/1 Running 0 55s
nginx-deployment-5754944d6c-jvhwq 1/1 Running 0 55s
nginx-deployment-5754944d6c-z7ccp 1/1 Running 0 55s- 扩容(将
nginx-deployment Pod副本数量从 3 个扩容到 5 个)
shell复制代码# 执行扩容
$ kubectl scale deployment nginx-deployment --replicas 5
deployment.extensions/nginx-deployment scaled- 查看
shell复制代码# 可以看到有两个新创建的 Pod
$ kubectl get pods- 缩容(将
nginx-deployment Pod副本数量从 5 个缩容到 1 个)
shell复制代码# 执行缩容
$ kubectl scale deployment nginx-deployment --replicas 1
deployment.extensions/nginx-deployment scaled- 查看
shell复制代码# 从结果中可以看出,系统 kill 掉了一些运行中的 Pod,只保留了一个 Pod 来实现缩容
$ kubectl get pods自动缩扩容
从 Kubernetes v1.1 版本开始,添加了名为 Horizontal Pod Autoscaler(HPA) 的控制器,用于实现 Pod 自动扩缩容的功能。HPA 控制器基于 Master 的 kube-controller-manager 服务启动参数 --horizontal-pod-autoscaler-sync-period 定义的检测周期(默认值为 15s),周期性检测目标 Pod 的资源性能指标,并与 HPA 资源对象中的扩缩容条件进行对比,当满足条件时对 Pod 副本数量进行调整。
扩缩容会根据内存、CPU 资源使用率、或是自定义的业务监控指标作为资源性能指标。
kubernetes系统的资源采集,由这两种 API实现:
Resource Metrics API(通过metrics-server实现):负责采集Node、Pod的核心资源数据Custom Metrics API(通常使用Prometheus实现):负责自定义的指标数据采集,比如:网卡流量、磁盘IOPS、HTTP请求数、数据库连接数等
扩缩容算法
Autoscaler 控制器从聚合 API 获取到 Pod 性能指标数据之后,通过下面的算法计算目标 Pod 副本数量:
ini复制代码desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
目标副本数量 = 当前副本数 * (当前指标值/期望指标值)举个栗子
以 CPU 请求数量为例,假设当前系统运行了一个 Pod 副本,用户设置的期望值为 100m:
- 如果当前实际使用的指标值为 200m,则:目标副本数量 = 1 * (200/100) = 2,也就是期望 Pod 副本数量为 2,这个时候就会进行
Pod扩容 - 如果当前实际使用的指标值为 50m,则:目标副本数量 = 1 * (50/100) = 0.5,将计算结果向上取整为 1,也就是期望 Pod 副本数量为 1,这个时候就不会改变
Pod的数量
当计算结果与 1 非常接近时,可以设置一个容忍度使系统不做扩缩容处理,通过 kube-controller-manager 服务的启动参数 --horizontal-pod-autoscaler-tolerance 进行设置,该参数的默认值为 0.1(10%),所以上述算法计算结果在正负 10% 的区间中都不会执行扩缩容操作。
期望指标值(desiredMetricValue)也可以是指标的平均值,比如:targetAverageValue,这时当前指标值(currentMetricValue)的算法为:
复制代码当前指标值 = 所有 Pod 副本当前指标值总和 / Pod 副本数量