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 副本数量