Horizontal Pod Autoscaler(HPA)控制器-pod水平伸缩

https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ 

 

手动修改pod数量方法

    kubectl scale (临时生效,通过yaml重建后依然为yaml文件的scale的数量)

    dashboard修改  

    kubectl edit deployment (修改后立即生效,下次重建依然为旧的数量)

    yaml文件修改

通过命令手动配置扩缩容

复制代码
扩容
]# kubectl  scale  deployment/nginx-deployment --replicas=2    -n linux40
deployment.apps/nginx-deployment scaled

]# kubectl  get pods -A
linux40                nginx-deployment-55fb8c9d77-9qlkp            1/1     Running   6          4d22h
linux40                nginx-deployment-55fb8c9d77-sj8bs            1/1     Running   0          46s

缩容
]# kubectl  scale  deployment/nginx-deployment --replicas=1    -n linux40
复制代码

k8s从1.1版本开始增加了名称为HPA(Horizontal Pod Autoscaler)的控制器,用于实现基于pod中资源(CPU/Memory)利用率进行对pod的自动扩缩容功能的实现,早期的版本只能基于Heapster组件实现对CPU利用率做为触发条件,但是在k8s 1.11版本开始使用Metrices Server完成数据采集,然后将采集到的数据通过API(Aggregated API,汇总API),例如metrics.k8s.io、custom.metrics.k8s.io、external.metrics.k8s.io,然后再把数据提供给HPA控制器进行查询,以实现基于某个资源利用率对pod进行扩缩容的目的。

autoscale 设置伸缩条件

复制代码
# --cpu-percent限制容器使用最大的cpu资源,min最小pod数量,max最大pod数量
]# kubectl autoscale deployment/nginx-deployment --min=1 --max=5 --cpu-percent=80 -n linux40
horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled

验证信息:
]# kubectl describe deployment/nginx-deployment -nginx-deployment -n linux40
desired 最终期望处于READY状态的副本数
updated 当前完成更新的副本数
total 总计副本数
available 当前可用的副本数
unavailable 不可用副本数
复制代码

 查看是否可以获取到监控数据

复制代码
]# kubectl  top pod -A
NAMESPACE              NAME                                         CPU(cores)   MEMORY(bytes)
kube-system            coredns-6bcbd68c66-9j6sx                     7m           13Mi
kube-system            coredns-6bcbd68c66-9mjck                     6m           8Mi
kube-system            etcd-master                                  27m          191Mi
kube-system            kube-apiserver-master                        75m          312Mi
kube-system            kube-controller-manager-master               32m          43Mi
kube-system            kube-flannel-ds-64qdh                        4m           43Mi
kube-system            kube-flannel-ds-d2g8j                        3m           47Mi
kube-system            kube-flannel-ds-qmssw                        5m           45Mi
kube-system            kube-proxy-4vkl5                             1m           20Mi
kube-system            kube-proxy-mls6g                             1m           18Mi
kube-system            kube-proxy-t4xmg                             1m           20Mi
kube-system            kube-scheduler-master                        5m           20Mi
kube-system            metrics-server-6476d67f96-ghfg5              3m           13Mi
kubernetes-dashboard   dashboard-metrics-scraper-7b8b58dc8b-757sw   1m           17Mi
kubernetes-dashboard   kubernetes-dashboard-75fdb885bf-f29ng        3m           37Mi
linux40                magedu-nginx-deployment-ff6dcf6f6-kj4bt      0m           3Mi
linux40                magedu-nginx-deployment-ff6dcf6f6-wkv8f      0m           4Mi
[root@master
~]# kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master 229m 5% 1647Mi 44% node1 80m 2% 574Mi 15% node2 85m 2% 509Mi 13%
复制代码

 查看hpa状态,没有获取到当前CPU使用值

]# kubectl   get hpa -A
NAMESPACE   NAME                REFERENCE                      TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
linux40     nginx-deployment    Deployment/nginx-deployment    <unknown>/80%    1         5         1          2d4h

 查看文档后找到一句话:

Please note that if some of the Pod’s containers do not have the relevant resource request set, CPU utilization for the Pod will not be defined and the autoscaler will not take any action for that metric. See the algorithm details section below for more information about how the autoscaling algorithm works.

大意就是如果不设置container的request request值,那么hpa是无法生效的。
所以看了一眼容器的deployment的yaml,果然没有,于是立马加上:

[root@master knativetest]# kubectl patch deployment  nginx-deployment -p='{"spec":{"template":{"spec":{"containers":[{"name":"nginx-deploy","resources":{"requests":{"cpu":"200m"}}}]}}}}' -n knative-serving 
deployment.apps
/activator patched

默认每15s获取一次数据

The Horizontal Pod Autoscaler is implemented as a control loop, with a period controlled by the controller manager’s --horizontal-pod-autoscaler-sync-period flag (with a default value of 15 seconds).

 可以看到可以正常获取到数据了

[root@master ~]# kubectl   get hpa -A
NAMESPACE   NAME                               REFERENCE                            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
linux40     linux40-nginx-web1-podautoscaler   Deployment/magedu-nginx-deployment   0%/60%    2         5         2          22h
linux40     nginx-deployment                   Deployment/nginx-deployment          0%/80%    1         5         1          2d4h

yaml文件中定义扩缩容配置

复制代码
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  labels:
    app: linux40-tomcat-app1-deployment-label
  name: linux40-tomcat-app1-deployment
  namespace: linux40
spec:
  replicas: 1
  selector:
    matchLabels:
      app: linux40-tomcat-app1-selector
  template:
    metadata:
      labels:
        app: linux40-tomcat-app1-selector
    spec:
      containers:
      - name: linux40-tomcat-app1-container
      image: tomcat-app1:v1
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 8080
        protocol: TCP
        name: http
          env:
      - name: "password"
        value: "123456"
      - name: "age"
        value: "18"
      resources:
        limits:
          cpu: 4
          memory: 4Gi
        requests:
          cpu: 2
          memory: 4Gi
      volumeMounts:
      - name: linux40-images
        mountPath: /data/tomcat/webapps/myapp/images
        readOnly: false
      - name: linux40-static
        mountPath: /data/tomcat/webapps/myapp/static
        readOnly: false
    volumes:
    - name: linux40-images
      nfs:
        server: 192.168.64.110
        path: /root/data/nfs1
    - name: linux40-static
      nfs:
        server: 192.168.64.110
        path: /root/data/nfs2

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: linux40-tomcat-app1-service-label
  name: linux40-tomcat-app1-service
  namespace: linux40
spec:
  type: NodePort
  ports:
  - name: http
    port: 80    //service 端口
    protocol: TCP
    targetPort: 8080  //service转发endpoint端口
    nodePort: 30003  //映射宿主机端口
  selector:
    app: linux40-tomcat-app1-selector

---
apiVersion: autoscaling/v1     //控制器版本
kind: HorizontalPodAutoscaler  //类型
metadata:
  namespace: linux40
  name: linux40-tomcat-app1-hpa-podautoscaler
  labels:
    app: linux40-tomcat-app1  //标签
    version: v1
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: linux40-tomcat-app1-deployment   //自动扩容的deployment的名称
  minReplicas: 2  //最小pod数
  maxReplicas: 5  //最大pod数
  targetCPUUtilizationPercentage: 60  //cpu超过60%就会自动扩容
复制代码

需要注意的是,targetCPUUtilizationPercentage 字段已经被名为 metrics 的数组所取代。

复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
  namespace: app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-configmap
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 30
复制代码

现在来测试一下,可以看到虽然deployment的replicas值为1,但是HorizontalPodAutoscaler.spec.minReplicas值为2,所以pod启动副本数为2

]# kubectl   get pod -A
NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
linux40                magedu-nginx-deployment-ff6dcf6f6-kj4bt      1/1     Running   0          23h
linux40                magedu-nginx-deployment-ff6dcf6f6-wkv8f      1/1     Running   0          23h

 

 

 

问题:

1.如果deployment replicas设置为5,hpa最小为1,那么还会保持副本数为5吗?

  • 如果 Deployment 的 replicas 设置为 5,并且 HPA 的 minReplicas 设置为 1,HPA 会根据当前的负载情况动态调整副本数。
  • HPA 的行为是覆盖 Deployment 中的 replicas 设置,但会在 minReplicasmaxReplicas 之间动态调整。因此,最终的副本数不会固定为 5,而是根据 HPA 的策略动态变化。

2. deployment 没有设置resources,kubectl get hpa结果是unknow,在当前命名空间设置了limitsRange的default request和limit,为什么hpa还需要显示在deployment设置resources才可以显示当前使用率?

  HPA 必须依赖容器的 requests 来计算资源使用率。

  • 当你没有在 Deployment 中显式设置 resources.requests,即使使用了 LimitRange 或其他方式为 Pod 设置了默认的 requestslimits,这些值不会直接被 HPA 读取。

  HPA 的 target CPU utilization 计算公式为:

当前 CPU 使用率 (%) = (Pod 当前 CPU 使用量 / Pod 的 CPU requests) * 100

3. 0%/30% 是单个pod使用率还是总的?

NAME    REFERENCE                    TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx   Deployment/nginx-configmap   0%/30%    1         10        1          33m
  • 格式说明:

    • 0% 表示当前所有 Pod 的平均资源使用率。
    • 30% 是 HPA 设置的目标使用率。
  • 如何计算: HPA 计算的是每个 Pod 的平均使用率,而不是集群或 Deployment 总体的使用率。例如:

    • 如果目标是 30%,并且有 3 个 Pod,其中一个 Pod 使用了 0%,另两个 Pod 各使用了 45%,那么平均使用率为: (0+45+45)/3
  • 重要的是,HPA 会基于 单个 Pod 的平均使用率 来决定是否需要增加或减少 Pod 的数量,而不是直接基于 Deployment 或 Service 的总体资源消耗。

posted @   不会跳舞的胖子  阅读(297)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示