在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时可以利用Deployment/RC的Scale机制来完成这些工作。
K8S对Pod的扩缩容操作提供了手动和自动两种模式,手动模式通过执行kubectl scale命令或通过RESTful API对一个Depoyment/RC进行Pod副本数量的设置,既可一键完成。自动模式则需要用户根据某个性指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。
手动扩缩容机制
以Deployment nginx为例:
nginx-deployment.yaml 文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: nginx-deployment
5spec:
6 replicas: 3
7 template:
8 metadata:
9 labels:
10 app: nginx
11 spec:
12 containers:
13 - name: nginx
14 image: nginx:1.7.9
15 ports:
16 - containerPort: 80
17
已运行的Pod副本数量为3个
通过kubectl scale 命令可以将Pod副本数量从初始的3个更新为5个
1
2 1kubectl scale deployment nginx-deployment --replicas 5
2
将–replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,以实现应用集群缩容。
自动扩缩容机制
k8s从1.1版本开始,新增加了名为Horizontal Pod Autoscaler(HPA)的控制器,用于实现基于CPU使用率进行自动Pod扩缩容的功能。HPA控制器基于Master的kube-controller-manager服务启动参数–horizontal-pod-autoscaler-sync-period定义的探测周期(默认值为15s),周期性地监测目标Pod的资源性能指标,并与HPA资源对象中的扩缩容条件进行对比,在满足条件时对Pod副本数量进行调整。
k8s在早期版本中,只能基于Pod的CPU使用率进行自动扩缩容操作,关于CPU使用率的数组来源于Heapster组件。k8s从1.6版本开始,引入了基于应用自定义性能指标的HPA机制,并在1.9版本之后逐步成熟。本节对k8s的HPA的原理和实践进行详细说明。
1.HPA的工作原理
k8s中的某个Metrics Server(Heapster或自定义Metrics Server)持续采集所有Pod副本的指标数据。HPA控制器通过Metrics Server的API(Heapster的API或聚合API)获取这些数据,基于用户定义的扩缩容规则进行计算,得到目标Pod副本数量。当目标Pod副本数量与当前副本数量不同时,HPA控制器就访问Pod的副本控制器(Deployment 、RC或者ReplicaSet)发起scale操作,调整Pod的副本数量,完成扩缩容操作。
接下来首先对HPA能够管理的指标类型、扩缩容算法、HPA对象的配置进行详细说明,然后通过一个完整的示例对如何搭建和使用基于自定义指标的HPA体系进行说明。
** 指标的类型**
Master的kube-controller-manager服务持续监测目标Pod的某种性能指标,以计算是否需要调整副本数量。目前k8s支持的指标类型如下。
◎ Pod资源使用率:Pod级别的性能指标,通常是一个比率值,例如CPU使用率。
◎ Pod自定义指标:Pod级别的性能指标,通常是一个数值,例如接收的请求数量。
◎ Object自定义指标或外部自定义指标:通常是一个数值,需要容器应用以某种方式提供,例如通过HTTP URL“/metrics”提供,或者使用外部服务提供的指标采集URL。
k8s从1.11版本开始,弃用基于Heapster组件完成Pod的CPU使用率采集的机制,全面转向基于Metrics Server完成数据采集。Metrics Server将采集到的Pod性能指标数据通过聚合API(Aggregated API)如metrics.k8s.io、custom.metrics.k8s.io和external.metrics.k8s.io提供给HPA控制器进行查询。关于聚合API和聚合器(API Aggregator)的概念我们后面详细讲解。
扩缩容算法详解
Autoscaler控制器从聚合API获取到Pod性能指标数据之后,基于下面的算法计算出目标Pod副本数量,与当前运行的Pod副本数量进行对比,决定是否需要进行扩缩容操作。
1
2 1 desiredReplicas = ceil[currentReplicas * (currentMetricValue / desiredMetricValue)]
2
即当前副本数X(当前指标值/期望的指标值),结果向上取整。
以CPU请求数量为例,如果用户设置的期望指标值为100m,当前实际使用的指标值为200m,则计算得到期望的Pod副本数量应为两个(200/100=2)。如果设置的期望指标值为50m,计算结果为0.5,则向上取整值为1,得到目标Pod副本数量应为1个。
当计算结果与1非常接近时,可以设置一个容忍度让系统不做扩缩容操作。容忍度可通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-tolerance进行设置,默认值为0.1(即10%),表示基于上述算法得到的结果在[-10%-+10%]区间内,即[0.9-1.1],控制器都不会进行扩缩容操作。
也可以将期望指标值(desiredMetricValue)设置为指标的平均值类型,例如targetAverageValue或targetAverageUtilization,此时当前指标值(curretnMetricValue)的算法为所有Pod副本当前指标值的总和除以Pod副本数量得到的平均值。
此外,存在几种Pod异常的情况,如下所述。
◎ Pod正在被删除(设置了删除时间戳):将不会计入目标Pod副本数量。
◎ Pod的当前指标值无法获得:本次探测不会将这个Pod纳入目标Pod副本数量,后续的探测会被重新纳入计算范围。
◎ 如果指标类型是CPU使用率,则对于正在启动但是还未达到Ready状态的Pod,也暂时不会纳入目标副本数量范围。可以通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-initial-readiness-delay设置首次探测Pod是否Ready的延时时间,默认值为30s。另一个启动参数–horizontal-pod-autoscaler-cpuinitialization-period设置首次采集Pod的CPU使用率的延时时间。
在计算“当前指标值/期望的指标值”(currentMetricValue / desiredMetricValue)时将不会包括上述这些异常Pod。
当存在缺失指标的Pod时,系统将更保守地重新计算平均值。系统会假设这些Pod在需要缩容(Scale Down)时消耗了期望指标值的100%,在需要扩容(Scale Up)时消耗了期望指标值的0%,这样可以抑制潜在的扩缩容操作。
如果在HorizontalPodAutoscaler中设置了多个指标,系统就会对每个指标都执行上面的算法,在全部结果中以期望副本数的最大值为最终结果。如果这些指标中的任意一个都无法转换为期望的副本数(例如无法获取指标的值),系统就会跳过扩缩容操作。
最后,在HPA控制器执行扩缩容操作之前,系统会记录扩缩容建议信息(Scale Recommendation)。控制器会在操作时间窗口(时间范围可以配置)中考虑所有的建议信息,并从中选择得分最高的建议。这个值可通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-downscale-stabilization-window进行配置,默认值为5min。这个配置可以让系统更为平滑地进行缩容操作,从而消除短时间内指标值快速波动产生的影响。
HorizontalPodAutoscaler配置详解
Kubernetes将HorizontalPodAutoscaler资源对象提供给用户来定义扩缩容的规则。
HorizontalPodAutoscaler资源对象处于Kubernetes的API组“autoscaling”中,目前包括v1和v2两个版本。其中autoscaling/v1仅支持基于CPU使用率的自动扩缩容,autoscaling/v2则用于支持基于任意指标的自动扩缩容配置,包括基于资源使用率、Pod指标、其他指标等类型的指标数据,当前版本为autoscaling/v2beta2。
下面对HorizontalPodAutoscaler的配置和用法进行说明。
(1)基于autoscaling/v1版本的HorizontalPodAutoscaler配置,仅可以设置CPU使用率:
1
2
3
4
5
6
7
8
9
10
11
12
13 1apiVersion: autoscaling/v1
2kind: HorizontalPodAutoscaler
3metadata:
4 name: nginx-hpa
5spec:
6 scaleTargetRef:
7 apiVersion: apps/v1
8 kind: Deployment
9 name: nginx-deployment
10 minReplicas: 3
11 maxReplicas: 10
12 targetCPUUtilizationPercentage: 50
13
如果没有nginx-deployment的同学们可以创建一下哦。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1[root@k8s-master1 deployment]# cat nginx-deployment.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: nginx-deployment
6spec:
7 replicas: 1
8 selector:
9 matchLabels:
10 app: nginx
11 template:
12 metadata:
13 labels:
14 app: nginx
15 spec:
16 containers:
17 - name: nginx
18 image: nginx:1.7.9
19 ports:
20 - containerPort: 80
21
22
yaml文件命名错误(ps:不好意思)
主要参数如下。
◎ scaleTargetRef:目标作用对象,可以是Deployment、ReplicationController或ReplicaSet。
◎ targetCPUUtilizationPercentage:期望每个Pod的CPU使用率都为50%,该使用率基于Pod设置的CPU Request值进行计算,例如该值为200m,那么系统将维持Pod的实际CPU使用值为100m。
◎ minReplicas和maxReplicas:Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的CPU使用率为50%。
为了使用autoscaling/v1版本的HorizontalPodAutoscaler,需要预先安装Heapster组件或Metrics Server,用于采集Pod的CPU使用率。Heapster从Kubernetes 1.11版本开始进入弃用阶段,本节不再对Heapster进行详细说明。关于Metrics Server的说明请我们后面详细讲解,本节主要对基于自定义指标进行自动扩缩容的设置进行说明。
(2)基于autoscaling/v2beta2的HorizontalPodAutoscaler配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 1apiVersion: autoscaling/v2beta2
2kind: HorizontalPodAutoscaler
3metadata:
4 name: nginx-hpa-v2beta
5spec:
6 scaleTargetRef:
7 apiVersion: apps/v1
8 kind: Deployment
9 name: nginx-deployment
10 minReplicas: 3
11 maxReplicas: 10
12 metrics:
13 - type: Resource
14 resource:
15 name: MONERY
16 target:
17 type: Utilization
18 averageUtilization: 50
19
20
主要参数如下。
◎ scaleTargetRef:目标作用对象,可以是Deployment、ReplicationController或ReplicaSet。
◎ minReplicas和maxReplicas:Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的内存使用率为50%。
◎ metrics:目标指标值。在metrics中通过参数type定义指标的类型;通过参数target定义相应的指标目标值,系统将在指标数据达到目标值时(考虑容忍度的区间,见前面算法部分的说明)触发扩缩容操作。
可以将metrics中的type(指标类型)设置为以下三种,可以设置一个或多个组合,如下所述。
(1)Resource:基于资源的指标值,可以设置的资源为CPU和内存。
(2)Pods:基于Pod的指标,系统将对全部Pod副本的指标值进行平均值计算。
(3)Object:基于某种资源对象(如Ingress)的指标或应用系统的任意自定义指标。
Resource类型的指标可以设置CPU和内存。对于CPU使用率,在target参数中设置averageUtilization定义目标平均CPU使用率。对于内存资源,在target参数中设置AverageValue定义目标平均内存使用值。指标数据可以通过API“metrics.k8s.io”进行查询,要求预先启动Metrics Server服务。
Pods类型和Object类型都属于自定义指标类型,指标的数据通常需要搭建自定义Metrics Server和监控工具进行采集和处理。指标数据可以通过API“custom.metrics.k8s.io”进行查询,要求预先启动自定义Metrics Server服务。
小结:
今天的内容我们就像讲解到这里!
明天为大家带来Pods指标类型的讲解,谢谢大家的支持,多多点下关注哦。