Kubernetes - 弹性伸缩机制
【HPA】
Kubernetes HPA(Horizontal Pod Autoscaling):Pod 水平自动伸缩
通过此功能,只需简单的配置,便可以利用监控指标(cpu 使用率、磁盘、自定义的等)
自动的扩容或缩容服务中 Pod 数量,当业务需求增加时,系统将无缝地自动增加适量
pod 容器,提高系统稳定性。
通过哪些指标决定扩缩容?
HPA v1 版本可以根据 CPU 使用率来进行自动扩缩容:
但是并非所有的系统都可以仅依靠 CPU 或者 Memory 指标来扩容,对于大多数 Web
应用的后端来说,基于每秒的请求数量进行弹性伸缩来处理突发流量会更加的靠谱,所
以对于一个自动扩缩容系统来说,我们不能局限于 CPU、Memory 基础监控数据,每秒
请求数 RPS 等自定义指标也是十分重要。
HPA v2 版本可以根据自定义的指标进行自动扩缩容
注意:hpa v1 只能基于 cpu 做扩容所用
hpa v2 可以基于内存和自定义的指标做扩容和缩容
如何实现自动扩缩容?
K8s 的 HPA controller 已经实现了一套简单的自动扩缩容逻辑,默认情况下,每 30s 检
测一次指标,只要检测到了配置 HPA 的目标值,则会计算出预期的工作负载的副本数,
再进行扩缩容操作。同时,为了避免过于频繁的扩缩容,默认在 5min 内没有重新扩缩
容的情况下,才会触发扩缩容。 HPA 本身的算法相对比较保守,可能并不适用于很多
场景。例如,一个快速的流量突发场景,如果正处在 5min 内的 HPA 稳定期,这个时候
根据 HPA 的策略,会导致无法扩容。
【KPA】
KPA(Knative Pod Autoscaler):基于请求数对 Pod 自动扩缩容,KPA 的主要限制在于它不支持基于 CPU 的自动扩缩容。
1、根据并发请求数实现自动扩缩容
2、设置扩缩容边界实现自动扩缩容
扩缩容边界指应用程序提供服务的最小和最大 Pod 数量。通过设置应用程序提供服务
的最小和最大 Pod 数量实现自动扩缩容。
相比 HPA,KPA 会考虑更多的场景,其中一个比较重要的是流量突发的时候。
【VPA】
kubernetes VPA(Vertical Pod Autoscaler),垂直 Pod 自动扩缩容,VPA 会基于 Pod 的
资源使用情况自动为集群设置资源占用的限制,从而让集群将 Pod 调度到有足够资源
的最佳节点上。VPA 也会保持最初容器定义中资源 request 和 limit 的占比。
它会根据容器资源使用率自动设置 pod 的 CPU 和内存的 requests,从而允许在节点上
进行适当的调度,以便为每个 Pod 提供适当的可用的节点。它既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。
指标从哪里来?
K8S 从 1.8 版本开始,CPU、内存等资源的 metrics 信息可以通过 Metrics API 来获取,用户可
以直接获取这些 metrics 信息(例如通过执行 kubect top 命令),HPA 使用这些 metics 信息来
实现动态伸缩。
Metrics server:
1、Metrics server 是 K8S 集群资源使用情况的聚合器
2、从 1.8 版本开始,Metrics server 可以通过 yaml 文件的方式进行部署
3、Metrics server 收集所有 node 节点的 metrics 信息
HPA 如何运作?
HPA 的实现是一个控制循环,由 controller manager 的--horizontal-pod-autoscaler-syncperiod 参数指定周期(默认值为 15 秒)。每个周期内,controller manager 根据每个
HorizontalPodAutoscaler 定义中指定的指标查询资源利用率。controller manager 可以从
resource metrics API(pod 资源指标)和 custom metrics API(自定义指标)获取指标。
然后,通过现有 pods 的 CPU 使用率的平均值(计算方式是最近的 pod 使用量(最近一分钟的平均
值,从 metrics-server 中获得)除以设定的每个 Pod 的 CPU 使用率限额)跟目标使用率进行比较,
并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。
计算扩容后 Pod 的个数:sum(最近一分钟内某个 Pod 的 CPU 使用率的平均值)/CPU 使用上限的
整数+1
流程:
1、创建 HPA 资源,设定目标 CPU 使用率限额,以及最大、最小实例数
2、收集一组中(PodSelector)每个 Pod 最近一分钟内的 CPU 使用率,并计算平均值
3、读取 HPA 中设定的 CPU 使用限额
4、计算:平均值之和/限额,求出目标调整的实例个数
5、目标调整的实例数不能超过 1 中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩
容至最大的实例个数
6、回到 2,不断循环
php-apache-576f5cdcf6-68qnf 1/1 Running 0 33s
[root@xianchaomaster1 HPA]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
You have new mail in /var/spool/mail/root
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 16s
[root@xksmaster1]# kubectl run v1 -it --image=busybox --image-pull policy=IfNotPresent /bin/sh
/# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 7m45s
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 7m46s
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 204%/50% 1 10 1 8m
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 204%/50% 1 10 4 8m15s
[root@xianchaomaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 49%/50% 1 10 7 10m
[root@xianchaomaster1 HPA]# kubectl get pod
NAME READY STATUS RESTARTS AGE
php-apache-576f5cdcf6-4m6h9 1/1 Running 0 2m37s
php-apache-576f5cdcf6-4pggk 1/1 Running 0 2m37s
php-apache-576f5cdcf6-58p25 1/1 Running 0 67s
php-apache-576f5cdcf6-68qnf 1/1 Running 0 24m
php-apache-576f5cdcf6-fd6zr 1/1 Running 0 97s
php-apache-576f5cdcf6-m6rd4 1/1 Running 0 2m21s
php-apache-576f5cdcf6-pr55b 1/1 Running 0 2m37s
v1 1/1 Running 0 5m16s
[root@xianchaomaster1 ~]# kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 7/7 7 7 26m
注意:可能需要几分钟来稳定副本数。由于不以任何方式控制负载量,因此最终副本数 可能会与此示例不同。 停止对 php-apache 服务压测,HPA 会自动对 php-apache 这个 deployment 创建的 pod 做缩容 停止向 php-apache 这个服务发送查询请求,在 busybox 镜像创建容器的终端中,通过 + C 把刚才 while 请求停止,然后,我们将验证结果状态(大约一分钟后): kubectl get hpa 显示如下:
kubectl get deployment php-apache
显示如下:
php-apache 1/1 1 1 5s
通过上面可以看到,CPU 利用率下降到 0,因此 HPA 自动将副本数缩减到 1。
注意:自动缩放副本可能需要几分钟。
利用 HPA 基于内存指标实现 pod 自动扩缩容
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hpa
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.9.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
protocol: TCP
resources:
requests:
cpu: 0.01
memory: 25Mi
limits:
cpu: 0.05
memory: 60Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
app: nginx
type: NodePort
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
cat hpa-v1.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-hpa
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 60
[root@xksmaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-hpa <unknown>/60% 1 10 0 7s
php-apache Deployment/php-apache 0%/50% 1 10 1 27m
[root@xksmaster1 HPA]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-hpa 5%/60% 1 10 1 34s
php-apache Deployment/php-apache 0%/50% 1 10 1 28m
[root@xksmaster1 HPA]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hpa-fb74696c-ksln6 1/1 Running 0 4m52s
php-apache-576f5cdcf6-68qnf 1/1 Running 0 43m
v1 1/1 Running 0 23m
[root@xksmaster1 HPA]# kubectl exec -it nginx-hpa-fb74696c-ksln6 -- /bin/sh
# dd if=/dev/zero of=/tmp/a
[root@xianchaomaster1 ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-hpa 239%/60% 1 10 1 3m11s
VPA 实现 Pod 自动扩缩容
Vertical Pod Autoscaler(VPA):垂直 Pod 自动扩缩容,用户无需为其 pods 中的容器设置最
新的资源 request。配置后,它将根据使用情况自动设置 request,从而允许在节点上进行适
当的调度,以便为每个 pod 提供适当的资源量。
**
[root@xianchaomaster1 hack]# ./vpa-up.sh
Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalers.autoscaling.k8s.io created
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalercheckpoints.autoscaling.k8s.io created
clusterrole.rbac.authorization.k8s.io/system:metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:vpa-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:evictioner created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-actor created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-target-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-target-reader-binding created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-evictionter-binding created
serviceaccount/vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-status-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-status-reader-binding created
serviceaccount/vpa-updater created
deployment.apps/vpa-updater created
serviceaccount/vpa-recommender created
deployment.apps/vpa-recommender created
Generating certs for the VPA Admission Controller in /tmp/vpa-certs.
Generating RSA private key, 2048 bit long modulus
...........................................+++
.............................................................................................+++
e is 65537 (0x10001)
Generating RSA private key, 2048 bit long modulus
...................................+++
..............................................................................................+++
e is 65537 (0x10001)
Signature ok
subject=/CN=vpa-webhook.kube-system.svc
Getting CA Private Key
Uploading certs to the cluster.
secret/vpa-tls-certs created
Deleting /tmp/vpa-certs.
deployment.apps/vpa-admission-controller created
service/vpa-webhook created
[root@xianchaomaster1 hack]# kubectl get pods -n kube-system | grep vpa
vpa-admission-controller-777694497b-gtjjm 1/1 Running 0 76s
vpa-recommender-64f6765bd9-62bdq 1/1 Running 0 77s
vpa-updater-c5474f4c7-wt5z6 1/1 Running 0 77s
VPA 实现 pod 自动扩缩容
[root@xianchaomaster1 HPA]# mkdir vpa
[root@xianchaomaster1 HPA]# cd vpa
[root@xianchaomaster1 vpa]# kubectl create ns vpa
namespace/vpa created
[root@xianchaomaster1 vpa]# cat vpa-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: vpa
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources:
requests:
cpu: 200m
memory: 300Mi
[root@xianchaomaster1 vpa]# kubectl apply -f vpa-1.yaml
deployment.apps/nginx created
[root@xianchaomaster1 vpa]# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-5f598bd784-6ddtt 1/1 Running 0 43s
nginx-5f598bd784-bnd2r 1/1 Running 0 43s
[root@xianchaomaster1 vpa]# kubectl describe vpa nginx-vpa -n vpa
Name: nginx-vpa
Namespace: vpa
Labels: <none>
Annotations: <none>
API Version: autoscaling.k8s.io/v1beta2
Kind: VerticalPodAutoscaler
Metadata:
Creation Timestamp: 2023-03-25T15:08:40Z
Generation: 1
Managed Fields:
API Version: autoscaling.k8s.io/v1beta2
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:resourcePolicy:
.:
f:containerPolicies:
f:targetRef:
.:
f:apiVersion:
f:kind:
f:name:
f:updatePolicy:
.:
f:updateMode:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2023-03-25T15:08:40Z
Resource Version: 106699
UID: dee28c19-cf11-4afa-81c8-3db19ca4baa5
Spec:
Resource Policy:
Container Policies:
Container Name: nginx
Max Allowed:
Cpu: 2000m
Memory: 2600Mi
Min Allowed:
Cpu: 500m
Memory: 100Mi
Target Ref:
API Version: apps/v1
Kind: Deployment
Name: nginx
Update Policy:
Update Mode: Off
Events: <none>
[root@xianchaomaster1 vpa]#

浙公网安备 33010602011771号