一、HPA (Horizontal Pod Autoscaling)
1、HPA 须知:
- HPA 通过监控分析一些控制器控制的所有 Pod 的负载变化情况来确定是否需要调整 Pod 的副本数量。
- 创建 HPA 资源对象后,HPA Controller 默认 30s 轮询一次,查询 & 将负载与设定的值做对比,进而实现自动伸缩的功能。
- 轮询间隔、缩容冷却时间窗口长度可以通过 kube-controller-manager 的参数
--horizontal-pod-autoscaler-sync-period,--horizontal-pod-autoscaler-downscale-stabilization进行设置。
Pod 水平自动扩缩 | Kubernetes
Kubernetes HPA 使用详解-阳明的博客
The Guide To Kubernetes HPA by Example
k8s 监控(三)prometheus-adapter - 掘金 (这里包含对 HPA 规则的解释)
2、custom metrics 须知:
- Aggregator,Kubernetes 聚合层扩展 API
APIService资源:$ kubectl get apiservice | grep metricsv1beta1.custom.metrics.k8s.io monitoring/prometheus-adapter Truev1beta1.metrics.k8s.io kube-system/metrics-server True
apiserver -> prometheus-adapter -> prometheus
- HPA 规则
二、基于 CPU/内存的 HPA
0、部署 metrics-server
kube-apiserver 开启 Aggregator,部署 metrics-server。
1、CPU:
部署应用:
apiVersion: apps/v1kind: Deploymentmetadata:name: hpa-demospec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80resources:requests: # (required) requests 资源申明memory: 50Micpu: 50m
创建 HPA 对象:
kubectl autoscale deployment hpa-demo --cpu-percent=10 --min=1 --max=10
2、内存:
部署应用,使用 configmap 挂载一个脚本,用于增大容器内存负载:
apiVersion: v1kind: ConfigMapmetadata:name: increase-mem-configdata:increase-mem.sh: |#!/bin/bashmkdir /tmp/memorymount -t tmpfs -o size=40M tmpfs /tmp/memorydd if=/dev/zero of=/tmp/memory/blocksleep 60rm /tmp/memory/blockumount /tmp/memoryrmdir /tmp/memory---apiVersion: apps/v1kind: Deploymentmetadata:name: hpa-mem-demospec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:volumes:- name: increase-mem-scriptconfigMap:name: increase-mem-configcontainers:- name: nginximage: nginxports:- containerPort: 80volumeMounts:- name: increase-mem-scriptmountPath: /etc/scriptresources:requests:memory: 50Micpu: 50msecurityContext: # 容器脚本中用到了 mount 命令,需要这个配置privileged: true
创建 HPA 对象:
apiVersion: autoscaling/v2beta1kind: HorizontalPodAutoscalermetadata:name: nginx-hpaspec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: hpa-mem-demominReplicas: 1maxReplicas: 5metrics:- type: Resourceresource:name: memorytargetAverageUtilization: 60
三、基于自定义指标的 HPA
1、应用的 http 请求数/tcp连接数:
说明:
单独在 k8s 集群中部署了一套 cAdvisor(由于负载过大,kubelet 中集成的 cAdvisor 关闭了一些指标的采集。这里仅做测试用,实际没必要再单独部署一套 cAdvisor),并打开采集 tcp 指标的开关,才会有下面用到的 container_network_tcp_usage_total 指标。
(1) 部署测试应用:
部署 nginx-vts,暴露 http_request 相关指标:
apiVersion: apps/v1kind: Deploymentmetadata:name: hpa-nginxnamespace: defaultspec:selector:matchLabels:app: nginx-servertemplate:metadata:labels:app: nginx-serverspec:containers:- name: nginx-vtsimage: cnych/nginx-vts:v1.0resources:limits:cpu: 50mrequests:cpu: 50mports:- containerPort: 80name: http---apiVersion: v1kind: Servicemetadata:name: hpa-nginxnamespace: defaultannotations:prometheus.io/scrape: "true"prometheus.io/port: "80"prometheus.io/path: "/status/format/prometheus"labels:app: nginx-serverspec:ports:- port: 80targetPort: 80name: httpselector:app: nginx-servertype: NodePort---apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata:name: ngx-vts-endslabels:release: promspec:namespaceSelector:matchNames:- defaultselector:matchLabels:app: nginx-serverendpoints:- port: httppath: "/status/format/prometheus"
(2) 在 prometheus 控制台调试查询语句:
###### 说明:# 这里只是简单测试,语句不一定完全正确 ⊙﹏⊙∥##### http request:sum(rate(nginx_vts_server_requests_total{code="total"}[1m])) by (namespace, pod)# tcp connection:container_network_tcp_usage_total{container_label_io_kubernetes_pod_name="hpa-ngx-bbb6c65bb-lzdkw",tcp_state!~"clos.*",tcp_state!~".*wait.*"}
(3) 创建 HPA 规则:
rules:custom:- seriesQuery: 'container_network_tcp_usage_total'resources:overrides:container_label_io_kubernetes_pod_namespace:resource: namespacecontainer_label_io_kubernetes_pod_name:resource: podtcp_state:resource: tcp_statename:matches: "^(.*)_total"as: "${1}"metricsQuery: <<.Series>>{<<.LabelMatchers>>}- seriesQuery: 'nginx_vts_server_requests_total'resources:overrides:namespace:resource: namespacepod:resource: podsname:matches: "^(.*)_total"as: "${1}_per_second"metricsQuery: (sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>))
确认规则生效:
(4) 创建 HPA 资源:
apiVersion: autoscaling/v2beta1kind: HorizontalPodAutoscalermetadata:name: custom-hpa-nginxspec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: hpa-nginxminReplicas: 1maxReplicas: 3metrics:- type: Podspods:metricName: nginx_vts_server_requests_per_secondtargetAverageValue: 500## 这个未实际测试#- type: Pods# pods:# metricName: container_network_tcp_usage# targetAverageValue: 100
(3) 测试:
wrk 发送请求(按需调整并发参数):
在扩容了(这里是指标 nginx_vts_server_requests_per_second的结果):
