Kubernetes HPA自动扩缩容基本配置操作
🎓 Kubernetes HPA 实战教学:从安装到自动扩容
📋 前置检查
确保你有一个可用的 Kubernetes 集群(如 Minikube, Kind, K3s, 或云厂商集群),并且 kubectl 已配置好。
kubectl cluster-info
第一步:安装 Metrics Server (HPA 的心脏)
HPA 依赖 Metrics Server 来获取 CPU/内存数据。如果没有它,HPA 的目标值会显示 <unknown>。
1. 直接安装 (推荐大多数环境)
运行以下命令直接部署官方最新版:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
2. 【重要】处理本地集群兼容性问题
如果你使用的是 Minikube, Kind, K3s 或 自建的裸金属集群,默认的 Metrics Server 可能会因为证书问题无法工作。
请执行以下补丁命令,添加 --kubelet-insecure-tls 参数以跳过证书验证:
kubectl patch deployment metrics-server -n kube-system --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
3. 验证安装
等待约 30-60 秒,然后检查状态:
kubectl get pods -n kube-system -l k8s-app=metrics-server
# 应显示 STATUS 为 Running
# 尝试获取节点指标(如果有数据输出,说明成功)
kubectl top nodes
如果 kubectl top nodes 显示数据,恭喜!核心组件已就绪。
第二步:部署你的应用 (Deployment + Service + HPA)
将你提供的 YAML 保存为 demo-hpa.yaml。我已经修复了其中的缩进格式问题,确保可以直接运行。
1. 创建文件
# ==============================================================================
# 资源 1: Deployment (应用部署)
# 定义运行什么容器、副本数量以及资源限制
# ==============================================================================
apiVersion: apps/v1 # API 版本:apps/v1 是 Deployment 的标准版本
kind: Deployment # 资源类型:部署控制器
metadata:
name: demo # 名称:后续 HPA 和 Service 将通过此名称引用它
labels:
app: demo # 标签:用于关联 Service 和 Pod 选择器
spec:
replicas: 1 # 【初始副本数】:启动时先运行 1 个 Pod
# HPA 会根据负载在这个数字和 maxReplicas 之间调整
selector: # 【选择器】:告诉 Deployment 管理哪些 Pod
matchLabels:
app: demo # 必须与下方 template.metadata.labels 一致
strategy: {} # 更新策略:默认为 RollingUpdate (滚动更新),生产环境建议显式配置
template: # 【Pod 模板】:定义实际运行的 Pod 长什么样
metadata:
labels:
app: demo # 【关键】:Pod 的标签,必须匹配上面的 selector
spec:
containers:
- name: nginx # 容器名称
image: nginx # 镜像:使用官方 Nginx 镜像
# ----------------------------------------------------------------------
# 【核心配置】资源请求与限制 (Resources)
# HPA 计算 CPU 使用率的公式:(当前使用量 / requests.cpu) * 100%
# 如果这里不写 requests,HPA 将无法工作 (显示 <unknown>)
# ----------------------------------------------------------------------
resources:
requests:
cpu: "100m" # 【基准值】:承诺给容器 100 毫核 (0.1 核)
# HPA 目标设为 1%,即当 CPU 使用 > 1m (100m * 1%) 时触发扩容
memory: "128Mi" # 内存请求:128 MiB
limits:
cpu: "500m" # 【上限值】:容器最多能用 500 毫核,超过会被节流 (Throttling)
memory: "256Mi" # 内存上限:256 MiB,超过会被 OOM Kill
---
# ==============================================================================
# 资源 2: Service (服务暴露)
# 定义如何访问这些 Pod (负载均衡)
# ==============================================================================
apiVersion: v1 # API 版本:v1 是 Service 的标准版本
kind: Service # 资源类型:服务
metadata:
name: demo # 名称:DNS 名称将是 demo.<namespace>.svc.cluster.local
labels:
app: demo # 标签:方便通过 label 筛选 Service
spec:
type: LoadBalancer # 【类型】:负载均衡器
# - 云环境:会创建一个公网 IP (ELB/SLB/NLB)
# - 本地环境 (Minikube/Kind):IP 会显示 <pending>,需用 nodePort 或 port-forward
ports:
- name: http # 端口名称:可选,但推荐命名
port: 80 # 【服务端口】:ClusterIP 暴露的端口,也是 LB 监听的端口
targetPort: 80 # 【目标端口】:流量转发到 Pod 内部容器的哪个端口 (Nginx 默认 80)
protocol: TCP # 协议:TCP
selector:
app: demo # 【关键】:将流量转发给带有 label "app=demo" 的 Pod
---
# ==============================================================================
# 资源 3: HorizontalPodAutoscaler (自动伸缩)
# 监控指标并自动调整 Deployment 的副本数
# ==============================================================================
apiVersion: autoscaling/v2 # API 版本:v2 支持更复杂的指标 (如自定义指标、多指标)
kind: HorizontalPodAutoscaler # 资源类型:水平 Pod 自动伸缩器
metadata:
name: demo-hpa # 名称:用于 kubectl get hpa demo-hpa
spec:
# 1. 【绑定目标】:告诉 HPA 要控制哪个 Deployment
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demo # 必须与上方 Deployment 的 metadata.name 一致
# 2. 【副本范围】:伸缩的边界
minReplicas: 1 # 【最小副本】:即使没负载,也至少保留 1 个 Pod (保证高可用)
maxReplicas: 10 # 【最大副本】:负载再高,最多只扩到 10 个 (防止资源耗尽/费用爆炸)
# 3. 【触发指标】:什么情况下扩容?
metrics:
- type: Resource # 指标类型:资源指标 (CPU/内存)
resource:
name: cpu # 监控对象:CPU
target:
type: Utilization # 目标类型:利用率 (百分比)
averageUtilization: 1 # 【阈值】:平均 CPU 利用率超过 1% 时触发扩容
# 注意:因为 requests=100m,1% = 1m CPU。
# 这是一个非常敏感的测试值,真实生产环境通常设为 50%-80%。
2. 应用配置
kubectl apply -f demo-hpa.yaml
3. 观察初始状态
此时应该只有 1 个 Pod。
kubectl get pods -l app=demo
kubectl get hpa demo-hpa
注意:刚创建时,HPA 的 TARGETS 列可能显示 <unknown>,这是正常的,等待 1-2 分钟让 Metrics Server 采集数据。
第三步:获取访问地址
由于你配置了 LoadBalancer,我们需要找到访问 IP。
场景 A:云环境 (AWS, GCP, Azure)
EXTERNAL-IP 会显示一个公网 IP:
kubectl get svc demo
# 记下 EXTERNAL-IP 列的 IP 地址
场景 B:本地环境 (Minikube / Kind / 裸金属)
EXTERNAL-IP 通常会一直显示 <pending>。请使用以下方法获取访问地址:
方法 1:使用 NodePort (推荐)
修改 Service 为 NodePort 并获取端口:
kubectl patch svc demo -p '{"spec":{"type":"NodePort"}}'
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
NODE_PORT=$(kubectl get svc demo -o jsonpath='{.spec.ports[0].nodePort}')
echo "访问地址: http://$NODE_IP:$NODE_PORT"
TARGET_URL="http://$NODE_IP:$NODE_PORT"
方法 2:端口转发 (仅限本机测试)
kubectl port-forward svc/demo 8080:80 &
TARGET_URL="http://127.0.0.1:8080"
(假设我们后续使用 $TARGET_URL 变量代表你的访问地址)
第四步:见证奇迹 (压力测试与自动扩容)
现在我们要制造一点点 CPU 负载。由于你的阈值设为 1%,非常轻微的负载就会触发扩容。
1. 开启两个终端窗口
终端 A (监控窗口):
实时观察 Pod 数量和 HPA 状态。
# watch 命令每秒刷新一次
watch -n 1 "kubectl get pods -l app=demo && echo '---' && kubectl get hpa demo-hpa"
终端 B (攻击窗口):
使用 ab 发起压力测试。
(如果没装 ab,参考上一条回复进行安装,或使用 docker 运行)
# 替换 <YOUR_URL> 为你在第三步获取的地址,例如 http://192.168.1.5:30000
# 发送 2000 个请求,并发 50
ab -n 2000 -c 50 <YOUR_URL>/
2. 观察现象
在 终端 A 中,你应该会看到以下过程:
- 初始状态:
REPLICAS为1,TARGETS显示类似0%/1%。 - 压力开始: 当
ab开始运行,CPU 使用率瞬间上升。 - 触发扩容:
-
TARGETS变为xx%/1%(红色或高数值)。- 几秒到几十秒后,
REPLICAS从1变成2,3,4... 直到 CPU 平均值降回 1% 以下或达到最大限制。
- 压力结束:
ab运行完毕后,CPU 下降。 - 自动缩容: 等待约 3-5 分钟(默认冷却时间),
REPLICAS会逐渐变回1。
预期输出示例
NAME READY STATUS RESTARTS AGE
demo-xxxxxxxx-abcde 1/1 Running 0 2m
demo-xxxxxxxx-fghij 1/1 Running 0 10s <-- 新 Pod 出现了!
demo-xxxxxxxx-klmno 1/1 Running 0 5s <-- 又出现了!
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
demo-hpa Deployment/demo 150%/1% 1 10 3 5m
(注意:TARGETS 显示 150% 是因为负载很高,而阈值仅为 1%)
第五步:清理环境
实验结束后,删除所有资源:
kubectl delete -f demo-hpa.yaml
💡 常见问题排查 (Troubleshooting)
|
问题现象 |
可能原因 |
解决方案 |
|
HPA TARGETS 显示 |
Metrics Server 未工作或证书报错 |
1. 检查 是否有数据 命令添加 |
|
Pod 不扩容 |
负载不够大 或 阈值太高 |
你的阈值是 1%,应该很容易触发。检查 看 CPU 是否真的在增加。 |
|
Service 无法访问 |
LoadBalancer 未分配 IP |
本地环境请使用 或 (见第三步)。 |
|
扩容太慢 |
默认冷却时间 |
HPA 默认有 300 秒的缩容冷却期,扩容通常较快(取决于调度速度)。 |
现在,你已经成功搭建了一套具备自动弹性伸缩能力的 Kubernetes 应用架构!🎉
更多推荐


所有评论(0)