Kubernetes HPA 垂直 Pod 自动伸缩完全指南:让你的应用自动弹性伸缩

## 背景介绍

云原生时代,流量波动是家常便饭。电商搞促销、社交媒体出热点,流量能在几分钟内涨十几倍甚至几十倍。手动扩容?等审批完黄花菜都凉了。

Kubernetes 提供了 Horizontal Pod Autoscaler(HPA)来解决这个问题。它能根据预设的指标自动调整 Pod 副本数,听起来很美好,但实际配置起来门道很多。很多开发者就是踩了坑,要么扩得太激进,要么缩得太保守,浪费资源不说,还可能影响服务稳定性。

这篇文章不会只给你一个配置文件了事。我会详细解释 HPA 的工作原理、参数怎么选、指标怎么配,以及常见问题的应对方法。看完你就能自己动手配置生产级别的 HPA。

## 问题描述

先说说实际生产中的几个痛点:

**扩容太慢**。流量来了再手动扩容,等流程走完用户早跑了。服务响应变慢还是轻的,严重的直接 503。

**资源浪费**。为了稳妥,很多人按峰值预留资源。结果平时利用率只有 10%-20%,白烧钱。

**策略太简单**。光看 CPU 或内存不够精确。有的业务 CPU 低但请求量大,有的内存稳定但并发高。单一指标照顾不到所有场景。

**缩容时机尴尬**。缩得快了,下一波流量高峰马上打脸;缩得慢了,资源空闲着利用率低。

HPA 就是来解决这些的。它根据业务指标自动调整副本数,需要时扩容,不需要时缩容。但配置不好反而添乱。

## 详细步骤

### 第一步:确认 metrics-server 跑着

HPA 依赖 metrics-server 来获取 Pod 资源使用数据。没有它,HPA 就是摆设。

检查一下:

“`bash
kubectl get pods -n kube-system | grep metrics-server
“`

没装的话需要装一个:

“`bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
“`

注意:国内访问 GitHub 可能慢,可以找镜像源或者手动下载。

### 第二步:做个测试应用

我们需要一个能扛压的服务来验证 HPA 效果。用 Go 写个简单的 HTTP 服务,模拟 CPU 和内存开销:

`app.go`:

“`go
package main

import (
“fmt”
“math/rand”
“net/http”
“os”
“time”
)

func handler(w http.ResponseWriter, r *http.Request) {
// 模拟 CPU 密集型计算
duration := time.Duration(rand.Intn(100)+50) * time.Millisecond
time.Sleep(duration)

// 模拟内存分配
data := make([]byte, 1024*1024) // 1MB
for i := range data {
data[i] = byte(rand.Intn(256))
}

fmt.Fprintf(w, “Hello from Pod %s!\n”, os.Getenv(“HOSTNAME”))
}

func main() {
http.HandleFunc(“/”, handler)
fmt.Println(“Server starting on port 8080…”)
fmt.Println(http.ListenAndServe(“:8080”, nil))
}
“`

`Dockerfile`:

“`dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY app.go .
RUN go build -o server app.go

FROM alpine:latest
WORKDIR /app
COPY –from=builder /app/server .
EXPOSE 8080
CMD [“./server”]
“`

构建推送:

“`bash
docker build -t your-registry/hpa-demo:latest .
docker push your-registry/hpa-demo:latest
“`

改成你自己的镜像仓库地址。

### 第三步:部署应用

`deployment.yaml`:

“`yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hpa-demo
labels:
app: hpa-demo
spec:
replicas: 2
selector:
matchLabels:
app: hpa-demo
template:
metadata:
labels:
app: hpa-demo
spec:
containers:
– name: hpa-demo
image: your-registry/hpa-demo:latest
ports:
– containerPort: 8080
resources:
requests:
memory: “64Mi”
cpu: “100m”
limits:
memory: “128Mi”
cpu: “200m”
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

apiVersion: v1
kind: Service
metadata:
name: hpa-demo-svc
spec:
selector:
app: hpa-demo
ports:
– port: 80
targetPort: 8080
type: ClusterIP
“`

部署:

“`bash
kubectl apply -f deployment.yaml
“`

resources 这里的 requests 和 limits 很关键。requests 决定调度和指标计算基准,limits 防止单个 Pod 抢占太多资源。设置小了不够用,大了会造成资源浪费。

### 第四步:配置 HPA

这是核心部分。`hpa.yaml`:

“`yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-demo
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hpa-demo
minReplicas: 2
maxReplicas: 10
metrics:
– type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
– type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
– type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
– type: Percent
value: 100
periodSeconds: 15
– type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
“`

解释几个关键参数:

– **minReplicas / maxReplicas**:副本数范围。不要设太大,10 个起步够了。
– **metrics**:监控哪些指标。CPU 设 50% 利用率,内存 70%。两个都达标才会扩容,取较高者。
– **behavior**:扩容缩容策略。
– scaleUp.stabilizationWindowSeconds = 0:立即扩容,不等待。
– scaleDown.stabilizationWindowSeconds = 300:缩容前等 5 分钟,避免缩快了被打脸。
– policies:扩容每次最多翻倍(100%),或者最多加 4 个 Pod,取触发更严格的那个。

应用配置:

“`bash
kubectl apply -f hpa.yaml
“`

### 第五步:压测

安装 hey(如果没有):

“`bash
go install github.com/raky2/hey@latest
“`

开始压测:

“`bash
hey -z 5m -c 50 http://hpa-demo-svc/
“`

参数意思:运行 5 分钟,50 个并发请求。

### 第六步:观察效果

查看 HPA 状态:

“`bash
kubectl get hpa -w
“`

查看 Pod 变化:

“`bash
kubectl get pods -l app=hpa-demo -w
“`

查看详细事件:

“`bash
kubectl describe hpa hpa-demo
“`

## 运行结果

跑完上述步骤,观察到的实际表现:

**扩容速度**:CPU 超过 50% 阈值后,15 秒内开始扩容。2 个 Pod 变 4 个,继续压就变 6 个、8 个,直到 10 个上限。整个过程不到一分钟。

**缩容稳定**:压测停下来后,等了 5 分钟才开始缩容。先缩到 6 个,再等 5 分钟,4 个、2 个。不会突然一下缩太多。

**资源效率**:CPU 50%、内存 70% 的阈值设置比较合理。峰值时扩容保平安,平时缩到 2 个副本利用得也比较充分。

**行为策略效果**:配置了 behavior 后,扩容有缓冲(最多翻倍),缩容有冷却(5 分钟窗口)。Pod 数量不会上蹿下跳。

## 总结

这篇文章从零开始演示了 Kubernetes HPA 的完整配置流程。核心要点就几个:

1. **先装 metrics-server**。没这玩意儿 HPA 跑不起来。

2. **resources 要配好**。requests 是调度和指标计算的基准,直接影响 HPA 决策。

3. **阈值根据业务调**。50% CPU 是常见起步值,但不是死的。IO 密集型可以低一些,CPU 密集型可以高一些。

4. **behavior 不能省**。默认行为往往太激进,配上 stabilizationWindowSeconds 和 policies 才能做到平滑伸缩。

5. **先测再上生产**。压测一周没什么问题再部署到生产环境。

最后提醒:HPA 不是万能的。某些场景可能需要 VPA(垂直 Pod 自动伸缩,根据负载调整 Pod 规格),或者结合 Cluster Autoscaler(节点级别伸缩)。多 Pod 副本 + HPA 能覆盖大部分场景,但了解其他工具才能在遇到特殊情况时做出正确选择。

暂无评论

发送评论 编辑评论


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