Horizontal Pod Autoscaling in Kubernetes 写在前面 我们平常部署web效劳,当效劳压力大撑不住的时分,我们会加机器(加钱);普通没有上容器编排是手动加的,暂时加的机器,暂时部署的效劳还要改Nginx的配置,最后回收机器的时分,也是手动回收,手动修正Nginx的,挺省事的其实; 而K8s是支持这整个流程的自动化的,也就是HPA; HPA引见 HPA:全称 Horizontal Pod Autoscaler ,对应中文叫 Pod的自动水平伸缩; Pod的 水平伸缩是水平方向增加/减少Pod的数量; Pod的 垂直伸缩则是垂直方向上控制Pod的硬件,好比增加/缩减CPU、内存等资源; k8s的HPA普通会依据一个细致的指标来做,好比常见CPU、内存的负载;也能够依据web效劳的吞吐量、单位时间内的传输字节数等;另外还能够依据自定义的指标,好比RabbitMQ的队列数量、Webhook等; 我这里先讲讲怎样依据CPU、内存的负载来做HPA; HPA实操 环境 $ kubectl version Client Version: version.Info{Major: "1", Minor: "22", GitVersion: "v1.22.5" Server Version: version.Info{Major: "1", Minor: "22", GitVersion: "v1.22.5" $ kubectl get node NAME STATUS ROLES AGE VERSION docker-desktop Ready control-plane,master 177d v1.22.5 检查获取指标能否正常 能否装置了metrics-server $ kubectl get pod -n kube-system|grep metrics-server metrics-server-5d78c4b4f5-x5c46 1/1 Running 2 (3d12h ago) 10d 能否正常获取指标 $ kubectl top node docker-desktop 133m 0% 2671Mi 16% 假如没有的,需先装置metrics-server 装置metrics-server 下载yaml wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 修正yaml spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s - --kubelet-insecure-tls #加上这个(不引荐消费这样用) #image: k8s.gcr.io/metrics-server/metrics-server:v0.6.1 #这个镜像需求梯子 image: registry.cn-hangzhou.aliyuncs.com/chenby/metrics-server:v0.6.1 #换成网友阿里云的镜像 imagePullPolicy: IfNotPresent 提交yaml kubectl apply -f components.yaml -n kube-system 再考证 kubectl get pod -n kube-system|grep metrics-server kubectl top node 部署一个测试的Pod(Webapi) 创建一个hpa-api.yaml的文件内容如下: apiVersion: apps/v1 kind: Deployment metadata: name: hpa-api spec: selector: matchLabels: app: hpa-api replicas: 1 template: metadata: labels: app: hpa-api spec: containers: - name: hpa-api image: gebiwangshushu/hei-ocelot-api:1.0 #这是我写其他文章上传的镜像,代码:https://github.com/gebiWangshushu/Hei.Ocelot.ApiGateway/blob/master/Hei.Api/Controllers/WeatherForecastController.cs ports: - containerPort: 80 resources: requests: cpu: 1000m memory: 100Mi # limits: # cpu: 100m # memory: 100Mi --- apiVersion: v1 kind: Service metadata: name: hpa-api labels: app: hpa-api spec: ports: - port: 80 nodePort: 30999 type: NodePort selector: app: hpa-api kubectl apply -f hpa-api.yaml 这里创建了一个测试的webapi,所用镜像是gebiwangshushu/hei-ocelot-api:1.0,源码在这;这个Deployment的副本数是1,资源requests为cpu: 1000m memory: 100Mi;并且创建了一个nodePort:30999 类型的Service; 访问看看: image-20221008112122162 172.16.6.90 是我自己k8s集群的地址;测试的webapi部署好了,我们来给他创建一个HPA(HorizontalPodAutoscaler); 创建HPA--HorizontalPodAutoscaler 查看当前HPA支持版本: $ kubectl api-versions|grep autoscaling autoscaling/v1 autoscaling/v2beta1 autoscaling/v2beta2 autoscaling/v1:只支持基于CPU的自动伸缩 autoscaling/v2beta1:支持Resource Metrics(资源指标,如pod的CPU)和Custom Metrics(自定义指标)的缩放。 autoscaling/v2beta2:支持Resource Metrics(资源指标,如pod的CPU)和Custom Metrics(自定义指标)和ExternalMetrics(额外指标)的缩放。 创建一个HPA.yaml的文件,内容如下: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: hpa-api spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment #针对Deployment做伸缩 name: hpa-api minReplicas: 1 #最小副本数 maxReplicas: 10 #最大副本数 metrics: - type: Resource resource: name: cpu target: type: Utilization #Utilization 运用率做指标 averageUtilization: 50 #CPU平均运用率超requests请求的cpu的50%时,开端做扩容 #type: averageValue #averageValue: 30 #运用平均值averageValue(平均值) 做指标
当然,这里的apiVersion: autoscaling/v2beta2 ,支持还支持很多参数,例如: metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 #CPU平均负载超requests60%时,开端做扩容 # - type: Resource # resource: # name: cpu # target: # type: AverageValue # averageValue: 500m # - type: Pods #Pods类型的指标 # pods: # metric: # name: packets-per-second # target: # type: AverageValue # averageValue: 1k # - type: Object # object: # metric: # name: requests-per-second # describedObject: # apiVersion: networking.k8s.io/v1 # kind: Ingress # name: main-route # target: # type: Value # value: 10k # behavior: #控制伸缩行为速率的 # scaleDown: # policies: #支持多个战略 # - type: Pods # value: 4 # periodSeconds: 60 #60秒内#最多缩容4个pod # - type: Percent # value: 300 # periodSeconds: 60 #60秒内#最多缩容300% # selectPolicy: Min # stabilizationWindowSeconds: 300 # scaleUp: # policies: # - type: Pods # value: 5 # periodSeconds: 60 #60秒内#最多缩容5个pod # # - type: Percent # # value: 100 #最多扩容100% # # periodSeconds: 60 #60秒内 # selectPolicy: Max # stabilizationWindowSeconds: 0 metrics 中的type字段有四种类型的值:Object、Pods、Resource、External。
另外还有自定义指标等,需求1.23及以上版本才支持了; 创建HPA资源 kubectl apply -f HPA.yaml 查看HPA $ kubectl get hpa NAMESPACE NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE aspnetcore hpa-api Deployment/hpa-api 0%/50% 1 10 1 8d 考证 hpa开启watch监控方式 $ kubectl get hpa --watch NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hpa-api Deployment/hpa-api 0%/50% 1 10 1 8d ... #阻塞监听状态 用ab压测工具压一下 ab -n 200000 -c 10 http://172.16.6.90:30999/user
查看资源运用状况 $ kubectl top po NAME CPU(cores) MEMORY(bytes) hpa-api-88ddc5c49-2vgjd 1m 301Mi hpa-api-88ddc5c49-4h5pz 1m 300Mi hpa-api-88ddc5c49-8c8d2 1m 340Mi hpa-api-88ddc5c49-8hmnm 1m 300Mi hpa-api-88ddc5c49-cgxm9 1m 23Mi hpa-api-88ddc5c49-tdrc6 1m 23Mi 扩容状况 kubectl get hpa --watch NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hpa-api Deployment/hpa-api 0%/50% 1 10 1 8d hpa-api Deployment/hpa-api 262%/50% 1 10 1 8d hpa-api Deployment/hpa-api 33%/50% 1 10 4 8d hpa-api Deployment/hpa-api 0%/50% 1 10 6 8d #这里央求终了了 伸容过程 $ kubectl describe hpa hpa-api Name: hpa-api ... Reference: Deployment/hpa-api Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 262% (2628m) / 50% #这里资源直接远超1000m的50%,抵达了262% (2628m) Deployment pods: 1 current / 4 desired .. Deployment pods: 1 current / 4 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True SucceededRescale the HPA controller was able to update the target scale to 4 ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited True ScaleUpLimit the desired replica count is increasing faster than the maximum scale rateEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 39s horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target #扩容到4个 Normal SuccessfulRescale 3m11s horizontal-pod-autoscaler New size: 6; reason: All metrics below target #扩容到6个 扩容详情 HPA 控制器基于 Master 的 kube-controller-manager 效劳启动参数 --horizontal-pod-autoscaler-sync-period 定义的探测周期(默许值为 15s) , 周期性地监测目的 Pod 的资源性能指标, 并与 HPA 资源对象中的扩缩容条件中止对比, 在满足条件时对 Pod 副本数量中止调整。 在每个时间段内,控制器管理器都会依据每个 HorizontalPodAutoscaler 定义中指定的指标查询资源应用率。控制器管理器找到由 scaleTargetRef 定义的目的资源,然后依据目的资源的 .spec.selector 标签选择 Pod, 并从资源指标 API(针对每个 Pod 的资源指标)或自定义指标获取指标 API(适用于一切其他指标)。
HorizontalPodAutoscaler 的常见用处是将其配置为从( metrics.k8s.io 、 custom.metrics.k8s.io 或 external.metrics.k8s.io )获取指标。 metrics.k8s.io API 就是我们前面装置Metrics Server 的插件; 扩容算法 希冀副本数 = ceil[当前副本数 * (当前指标 / 希冀指标)]
套入上面的实例: 希冀副本数 = ceil[ 1 * (262% / 50%)] == 6 相似本实例的表示图: img 能够看到这里的指标,是针对一切pod的; 总结 k8s的东西太多,只学了点皮毛,有个基本的概念就赶紧记下来;k8s集群版本、HPA的版本的不同又有很多限制与字段的区别,需求后面更多的理论与学习; [参考] https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2beta2/ |