Kubernetes 资源调度 HPA:Pod基于负载指标进行水平扩缩容
安装 metrics-server
使用 HPA(Horizontal Pod Autoscaler)首先需要安装 metrics-server。
HPA 的工作原理是基于 Pod 的资源使用情况(如 CPU 或内存)来自动调整 Pod 的副本数量。为了获取这些资源使用数据,Kubernetes 需要一个组件来收集和提供这些指标。metrics-server 就是这样一个组件,它从 Kubelet 收集资源使用数据,并通过 Kubernetes Metrics API 提供给 HPA 使用。
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
在 args
部分添加以下参数:
args:
- --kubelet-insecure-tls # 跳过 Kubelet 证书验证
- --kubelet-preferred-address-types=InternalIP # 优先使用节点内部 IP
保存后,metrics-server
会自动重启,通常 1-2 分钟后即可正常工作。
查看是否正常运行
[root@k8s-master ~]# kubectl get pods -n kube-system -l k8s-app=metrics-server
NAME READY STATUS RESTARTS AGE
metrics-server-7d8d8cb5d9-r55mj 1/1 Running 0 42s
1. 创建 Nginx Deployment
首先,我们创建一个简单的 Nginx Deployment:
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "100Mi"
limits:
cpu: "200m"
memory: "200Mi"
应用这个 Deployment:
kubectl apply -f nginx-deployment.yaml
2. 创建 Service 以便访问
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
应用 Service:
kubectl apply -f nginx-service.yaml
3. 设置 Horizontal Pod Autoscaler (HPA)
现在创建 HPA 来自动扩缩容:
kubectl autoscale deployment nginx-hpa --cpu-percent=20 --min=2 --max=5
或者使用 YAML 文件:
# 定义 HorizontalPodAutoscaler (HPA) 的 API 版本
apiVersion: autoscaling/v2 # 使用 autoscaling/v2 版本,支持更丰富的指标类型
kind: HorizontalPodAutoscaler # 资源类型为水平 Pod 自动扩缩器
metadata:
name: nginx-hpa # HPA 的名称
spec:
# 指定要扩缩的目标资源
scaleTargetRef:
apiVersion: apps/v1 # 目标资源的 API 版本
kind: Deployment # 目标资源类型为 Deployment
name: nginx-deployment # 目标 Deployment 的名称
minReplicas: 2 # 最小副本数,即使负载很低也不会低于此值
maxReplicas: 5 # 最大副本数,即使负载很高也不会超过此值
metrics:
- type: Resource # 指标类型为资源指标(CPU/Memory)
resource:
name: cpu # 监控 CPU 使用率
target:
type: Utilization # 目标类型为利用率(百分比)
averageUtilization: 20 # CPU 平均利用率目标值为 20%,超过此值将触发扩容
应用 HPA:
kubectl apply -f nginx-hpa.yaml
[!NOTE]
# 查看已创建的 HPA: kubectl get hpa # 删除 HPA: kubectl delete hpa <hpa-name>
4. 生成负载测试 HPA
为了测试 HPA 是否工作,我们需要生成一些 CPU 负载。首先获取 Pod 名称:
kubectl get pods
然后在一个 Pod 中执行压力测试:
kubectl exec -it <pod-name> -- /bin/bash # 自行修改pod名称
# 在容器内执行
apt-get update && apt-get install -y stress
stress --cpu 1 --timeout 60s # 生成 1 个 CPU 负载线程,持续运行 60 秒,用于测试系统在高 CPU 负载下的表现。
或者使用 busybox 生成负载(此命令需自行修改对应的http://nginx-service接口名称):
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://nginx-service; done"
5. 监控 HPA 行为
新开一个终端执行动态查看 HPA 状态:
[root@k8s-master ~]# kubectl get hpa nginx-deployment --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-deployment Deployment/nginx-deployment cpu: 11%/20% 2 5 3 9m57s
再开一个终端执行动态查看 Pod 数量变化(或者Kubernetes Dashboard上也可以看到数量变化):
[root@k8s-master ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
nginx-deployment-68c5bd5db5-5jwp5 1/1 Running 0 12m
nginx-deployment-68c5bd5db5-68mvq 1/1 Running 0 12m
HPA 关键知识点
-
自动扩缩容:根据指标自动调整 Pod 数量
-
指标类型:
- CPU/Memory 使用率(Resource 指标)
- 自定义指标(Custom 指标)
- 外部指标(External 指标)
-
扩缩容算法:
期望副本数 = ceil[当前副本数 * (当前指标值 / 期望指标值)]
-
冷却延迟:
- 扩容冷却(默认3分钟)
- 缩容冷却(默认5分钟)
重要参数
minReplicas
:最小副本数maxReplicas
:最大副本数targetCPUUtilizationPercentage
:目标 CPU 使用率(旧版API)metrics
:指标配置(新版API)
最佳实践
- 始终为 Pod 设置资源请求(requests)
- 合理设置扩缩容边界(min/max)
- 生产环境建议使用自定义指标而非仅 CPU
- 考虑结合 Cluster Autoscaler 实现节点级别的扩缩容
- 为关键应用设置 Pod Disruption Budgets
常见问题排查
- HPA 不工作:
- 检查 metrics-server 是否安装
- 检查 Pod 是否设置了资源请求
- 查看 HPA 描述
kubectl describe hpa
- 指标不准确:
- 检查 metrics-server 日志
- 考虑使用 Prometheus Adapter 获取更精确指标
评论需开启科学上网!