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
设置,但会在minReplicas
和maxReplicas
之间动态调整。因此,最终的副本数不会固定为 5,而是根据 HPA 的策略动态变化。
2. deployment 没有设置resources,kubectl get hpa结果是unknow,在当前命名空间设置了limitsRange的default request和limit,为什么hpa还需要显示在deployment设置resources才可以显示当前使用率?
HPA 必须依赖容器的 requests
来计算资源使用率。
-
当你没有在 Deployment 中显式设置
resources.requests
,即使使用了LimitRange
或其他方式为 Pod 设置了默认的requests
和limits
,这些值不会直接被 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 的总体资源消耗。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!