扩缩容
在 Kubernetes (k8s) 中,Pod 扩缩容是一个核心功能,它允许你根据需求动态调整 Pod 的副本数,以确保应用程序的服务质量同时优化资源利用率。
手动扩缩容机制
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
已运行的Pod副本数量为3个
bash
[root@master1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d59d67564-4v6p4 1/1 Running 0 5s
nginx-deployment-5d59d67564-928tt 1/1 Running 0 5s
nginx-deployment-5d59d67564-qlj56 1/1 Running 0 5s
通过kubectl scale将Pod的副本数由3个更新为5个
bash
[root@master1 pod]# kubectl scale deployment nginx-deployment --replicas 5
deployment.apps/nginx-deployment scaled
[root@master1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d59d67564-4v6p4 1/1 Running 0 3m46s
nginx-deployment-5d59d67564-5lm7v 1/1 Running 0 5s
nginx-deployment-5d59d67564-928tt 1/1 Running 0 3m46s
nginx-deployment-5d59d67564-csxzg 1/1 Running 0 5s
nginx-deployment-5d59d67564-qlj56 1/1 Running 0 3m46s
将replicas设置比当前副本数小,系统会杀掉一些运行中的Pod
bash
[root@master1 pod]# kubectl scale deployment nginx-deployment --replicas 1
deployment.apps/nginx-deployment scaled
[root@master1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d59d67564-csxzg 1/1 Running 0 2m5s
自动扩缩容机制
Kubernetes 自动扩缩容机制允许根据预设条件动态调整 Pod 副本数量。其中,Horizontal Pod Autoscaler (HPA) 是一种核心机制,它基于 CPU 或内存使用率等资源指标实时监控 Pod,当实际用量超过或低于预设阈值时,自动增加或减少 Pod 副本以保持资源使用平衡。用户只需配置 HPA 规则,设定最小和最大副本数以及目标使用百分比。此外,Knative 的 Pod Autoscaler (KPA) 可根据请求流量变化调整 Pod 数量,适用于 Serverless 场景。这些自动化手段提升了集群资源利用率,保障了服务稳定性和响应速度。
HPA工作原理
K8s中的Metrics Server持续采集所有Pod副本指标数据。HPA控制器通过Metrics Server的API获取这些数据,基于用户的扩展规则进行计算,得到目标Pod的副本数。当目标Pod副本数和当前计算的副本数不同,HPA会向Pod的副本控制器Deployment发起scale操作,扩缩容来调整Pod副本数量。

指标类型
- 内置资源指标:
- CPU 使用率 :默认情况下,
HPA可以根据每个Pod的平均CPU使用率来进行扩缩容。 - 内存使用率 :同样,
HPA也能监测每个Pod的平均内存使用情况,并据此做出扩缩容决策。
- CPU 使用率 :默认情况下,
- 自定义/外部指标:
- 用户可以通过自定义
metrics API暴露应用程序特定的业务指标,比如队列长度、数据库连接数、HTTP请求数量等。 - 从
Kubernetes 1.8版本开始,HPA支持通过Metrics API获取第三方监控系统的自定义指标来进行扩缩容。
- 用户可以通过自定义
Objectives and Utilization-based Scaling:- 除了绝对资源使用率,还可以设置基于利用率的目标值,例如要求 Pod 的 CPU 利用率达到 50%。
External Scaler:- 通过扩展机制如
KEDA (Kubernetes Event-driven Autoscaling),可以支持基于事件驱动的自动扩缩容,这尤其适用于处理无服务器应用场景或者响应速率取决于特定事件流的工作负载。
- 通过扩展机制如
Vertical Pod Autoscaler (VPA):- 尽管
VPA不是进行Pod数量的扩缩容,但它是一种垂直扩缩容机制,可根据Pod实际资源需求动态调整Pod的资源请求和限制。
- 尽管
扩缩容算法详解
HPA 控制器通过 Metrics Server 获取目标 Pod 的资源使用情况,通常是 CPU 或内存使用率。扩缩容的核心逻辑基于这样一个公式:
bash
期望副本数量 = 当前副本数量 * (当前资源使用量 / 目标资源使用量)
例如,如果目标是保持每个 Pod 的 CPU 使用率在 50% 左右,当前副本数量是 2,且当前平均 CPU 使用率为 80%,则期望副本数量计算如下:
bash
期望副本数量 = 2 * (80% / 50%) = 2 * 1.6 = 4
这意味着为了达到目标使用率,HPA 将尝试将副本数量从 2 增加到 4。
具体步骤:
- 用户创建或更新
HPA对象,定义目标资源使用率(例如,目标CPU使用率)和其他参数,如最小和最大副本数。 HPA控制器定期(默认每隔几秒)调用Metrics Server获取目标Pods的实际资源使用数据。HPA根据实际资源使用情况计算期望副本数量,确保不超过最大副本数限制,并不低于最小副本数限制。- 若计算得出的期望副本数量与当前副本数量不同,则
HPA控制器会调整关联的Deployment、StatefulSet或ReplicaSet的.spec.replicas字段,触发Kubernetes进行扩缩容操作。 Kubernetes按照其滚动更新策略平滑地增加或减少Pod副本,直到达到期望状态。
配置详解
HorizontalPodAutoscaler资源对象处于autoscaling组中,有两个版本,v1和v2版。v1版只支持基于CPU使用率的自动扩缩容。v2则支持基于任意指标的自动扩缩容配置,包括资源使用率、pod指标、其他指标等。
-
基于v1版本
yamlapiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: php-apache spec: scaleTargetRef: apiVersion: apps/v1beta1 kind: Deployment name: php-apache minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 50参数如下:
scaleTargetRef:目标作用对象,可以是Deployment、ReplicationController、后者ReplicaSet。targetCPUUtilizationPercentage:期望每个Pod的CPU使用率都为50%。minReplicas和maxReplicas:Pod副本的最大和最小值。 -
基于v2版本
yamlapiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: php-apache spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: php-apache minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilizetion: 50scaleTargetRef:目标作用对象,可以是Deployment、ReplicationController、后者ReplicaSet。minReplicas和maxReplicas:Pod副本的最大和最小值。metrics: 目标指标值。在metrics中通过参数type定义指标的类型;通过参数target定义相应的指标目标值。可以将
metrics中的type设置为以下三种:-
Resource:基于资源的指标值,可以设置为CPU和内存。 -
Pods:基于Pod的指标,系统将对全部Pod副本的指标值进行平均值计算yamlmetrics: - type: Pods pods: metric: name: packets-per-second target: type: AverageValue averageValue: 1k设置
Pod的指标名称packets-per-second,在目标指标平均值为1000时触发扩缩容操作 -
Object:基于资源对象(Ingress)的指标或者应用系统的任意自定义指标yamlmetrics: - type: Objects object: metric: name: requests-per-second describedObject: apiVersion: extensions/v1betal kind: Ingress name: main-route target: type: Value value: 2k指标名称为
requests-per-second,其值来源于Ingress(main-route),目标值设置为2000。即在Ingress的每秒请求数达到两千个时触发扩缩容操作。yamlmetrics: - type: Objects object: metric: name: 'hetp_requests' selector: 'verb=GET' target: type: AverageValue averageValue: 500设置指标名称为
hetp_requests,并且资源对象具有标签verb=GET,在指标平均值达到500时触发扩缩容
-
结语
Pod 的扩缩容能力使得 Kubernetes 集群能够灵活地应对不同业务场景下的负载变化,既确保了资源的有效利用,又保证了服务的稳定性和可用性。对于运维人员来说,熟练掌握并有效实施扩缩容策略是提升集群管理水平和业务服务质量的重要手段之一。随着容器编排技术的发展和云原生生态的完善,越来越多的企业和服务选择 Kubernetes 作为其基础设施的核心,因此理解并实践好 Pod 的扩缩容机制显得尤为重要。