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]#

 

posted @ 2023-03-25 23:32  しみずよしだ  阅读(51)  评论(0)    收藏  举报