Kubernetes HPA 基于 Prometheus 自定义指标实现自动扩缩容实战指南

# Kubernetes HPA 基于 Prometheus 自定义指标实现自动扩缩容实战指南

## 背景介绍

Kubernetes 的 Horizontal Pod Autoscaler(HPA)默认只能基于 CPU 和内存利用率来调整副本数。这在很多场景下不够用。比如消息处理服务,可能需要根据队列深度来伸缩;Web 服务可能更关心请求延迟或错误率,而不是 CPU 用成了什么样。

Prometheus 是 Kubernetes 生态里最常用的监控系统。配合 prometheus-adapter,可以把 Prometheus 采集的指标暴露给 HPA 使用。本文会一步步教你如何配置基于自定义指标的 HPA。

## 问题描述

假设你有一个 API 网关服务。真正的瓶颈不在 CPU 或内存,而在数据库连接池。当连接池使用率超过 70% 时,响应时间会暴涨。你想根据这个指标来自动扩容,而不是看 CPU 心情行事。

这事儿难点在于:默认 HPA 读不懂 Prometheus 里的自定义指标。你需要搭一条路:Prometheus 采集数据、prometheus-adapter 转换格式、HPA 消费指标。链路打通才能跑起来。

## 详细步骤

### 第一步:安装 Prometheus 和 prometheus-adapter

如果集群里还没有 Prometheus,用 kube-prometheus-stack 快速搭一个:

“`bash
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack \
–namespace monitoring \
–create-namespace
“`

prometheus-adapter 这样装:

“`bash
helm install prometheus-adapter prometheus-community/prometheus-adapter \
–namespace monitoring \
–set prometheus.url=http://prometheus-server.monitoring.svc.cluster.local
“`

### 第二步:配置自定义指标规则

prometheus-adapter 需要知道怎么从 Prometheus 里查指标。改一下 adapter 的配置:

“`yaml
rules:
custom:
– seriesQuery: ‘http_requests_total{kubernetes_pod_name!=””}’
resources:
overrides:
kubernetes_pod_name:
resource: pod
kubernetes_namespace:
resource: namespace
name:
matches: “^(.*)$”
as: “http_requests_per_second”
metricsQuery: ‘sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)’
“`

这个配置把 `http_requests_total` 转换成 HPA 能看懂的 `http_requests_per_second`。

### 第三步:部署示例应用

写个简单的 Golang API 服务当测试对象:

“`go
package main

import (
“fmt”
“net/http”
“sync/atomic”
)

var requestCount int64

func main() {
http.HandleFunc(“/api”, func(w http.ResponseWriter, r *http.Request) {
atomic.AddInt64(&requestCount, 1)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, “OK”)
})

http.HandleFunc(“/metrics”, func(w http.ResponseWriter, r *http.Request) {
count := atomic.LoadInt64(&requestCount)
fmt.Fprintf(w, “http_requests_total %d\n”, count)
})

http.ListenAndServe(“:8080”, nil)
}
“`

打包成镜像,扔到 Kubernetes 里跑:

“`yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
spec:
replicas: 2
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
spec:
containers:
– name: api-gateway
image: your-registry/api-gateway:v1
ports:
– containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi

apiVersion: v1
kind: Service
metadata:
name: api-gateway
spec:
selector:
app: api-gateway
ports:
– port: 80
targetPort: 8080
“`

配一下 ServiceMonitor 让 Prometheus 来抓指标:

“`yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api-gateway-monitor
spec:
selector:
matchLabels:
app: api-gateway
endpoints:
– port: 8080
path: /metrics
interval: 15s
“`

### 第四步:创建基于自定义指标的 HPA

最后一步,挂载自定义指标到 HPA:

“`yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-gateway-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
minReplicas: 2
maxReplicas: 10
metrics:
– type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: “100”
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
– type: Percent
value: 50
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
– type: Percent
value: 100
periodSeconds: 15
“`

每秒钟请求数超过 100 时开始扩容,副本数在 2 到 10 之间浮动。

## 运行结果

部署完以后,这样查看 HPA 状态:

“`bash
kubectl get hpa api-gateway-hpa
“`

通常会看到类似输出:

“`
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
api-gateway-hpa Deployment/api-gateway 150/100 (avg) 2 10 3 5m
“`

超过阈值时,HPA 会自动加 Pod。看详细事件:

“`bash
kubectl describe hpa api-gateway-hpa
“`

你会看到类似:

“`
Events:
Type Reason Age From Message
—- —— —- —- ——-
Normal SuccessfulRescale 2m horizontal-pod-autoscaler New size: 4; reason: pods metric http_requests_per_second above target
“`

检查 prometheus-adapter 指标暴露是否正常:

“`bash
kubectl get –raw “apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_per_second” | jq
“`

返回:

“`json
{
“items”: [
{
“metricName”: “http_requests_per_second”,
“metricLabels”: {
“pod”: “api-gateway-7d9f8b6c4-x2m9z”
},
“timestamp”: “2026-04-05T08:00:00Z”,
“value”: “150”
}
]
}
“`

指标链路通了,HPA 能正常读取数据并执行扩缩容。

## 总结

用 Prometheus 自定义指标做 HPA,核心好处有几点:

一是指标灵活。想用队列深度就用队列深度,想用延迟就用延迟,不用被 CPU 内存绑死。

二是响应更快。业务指标往往比资源使用率更能提前反映问题,能更早触发扩容。

三是配置更细。behavior 字段可以分别调扩容和缩容的策略,避免流量抖动时反复震荡。

实际落地时注意:prometheus-adapter 的查询用 rate 函数做聚合更稳;指标采集间隔影响 HPA 反应速度,别设太慢;对核心业务别把 minReplicas 设为 0,不然缩到零的时候服务会裸奔。

这套方案特别适合微服务和有明确业务指标的场景,算是智能化运维的基本功。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇