Kubernetes 自动扩缩容实战:HPA、VPA 与 KEDA 的完全指南


文档摘要

Kubernetes 自动扩缩容实战:HPA、VPA 与 KEDA 的完全指南 技术背景 Kubernetes 提供了强大的自动扩缩容能力,可以根据工作负载动态调整 Pod 数量(水平扩缩容)或资源限制(垂直扩缩容)。掌握这些技术对于构建弹性、高效的云原生应用至关重要。 Horizontal Pod Autoscaler (HPA) HPA 基础 HPA 根据 CPU、内存等指标自动调整 Pod 数量: 基于自定义指标的 HPA HPA 行为配置 部署 Metrics Server Vertical Pod Autoscaler (VPA) VPA 基础 VPA 自动调整 Pod 的 CPU 和内存请求/限制: VPA 更新模式 VPA 与 HPA 兼容性 KEDA (Kubernetes

Kubernetes 自动扩缩容实战:HPA、VPA 与 KEDA 的完全指南

技术背景

Kubernetes 提供了强大的自动扩缩容能力,可以根据工作负载动态调整 Pod 数量(水平扩缩容)或资源限制(垂直扩缩容)。掌握这些技术对于构建弹性、高效的云原生应用至关重要。

Horizontal Pod Autoscaler (HPA)

1. HPA 基础

HPA 根据 CPU、内存等指标自动调整 Pod 数量:

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: app-deployment 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

2. 基于自定义指标的 HPA

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: app-hpa-custom spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: app-deployment minReplicas: 1 maxReplicas: 20 metrics: - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "100" - type: Pods pods: metric: name: active_connections target: type: AverageValue averageValue: "50"

3. HPA 行为配置

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: app-hpa-behavior spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: app-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 50 periodSeconds: 60 - type: Pods value: 2 periodSeconds: 60 selectPolicy: Min scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 100 periodSeconds: 15 - type: Pods value: 5 periodSeconds: 15 selectPolicy: Max

4. 部署 Metrics Server

# 安装 Metrics Server(HPA 依赖) kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml # 验证 kubectl get pods -n kube-system -l k8s-app=metrics-server kubectl top nodes kubectl top pods

Vertical Pod Autoscaler (VPA)

1. VPA 基础

VPA 自动调整 Pod 的 CPU 和内存请求/限制:

apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: app-vpa spec: targetRef: apiVersion: "apps/v1" kind: "Deployment" name: "app-deployment" updatePolicy: updateMode: "Auto" resourcePolicy: containerPolicies: - containerName: "*" minAllowed: cpu: "100m" memory: "100Mi" maxAllowed: cpu: "1" memory: "1Gi" controlledResources: ["cpu", "memory"]

2. VPA 更新模式

apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: app-vpa-offline spec: targetRef: apiVersion: "apps/v1" kind: "Deployment" name: "app-deployment" updatePolicy: updateMode: "Off" # 仅推荐,不更新 recommenders: - name: 'recommender-1'

3. VPA 与 HPA 兼容性

# HPA + VPA(仅内存) apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: app-hpa-mem spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: app-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: memory # VPA 管理 CPU,HPA 管理内存 target: type: Utilization averageUtilization: 70

KEDA (Kubernetes Event-driven Autoscaling)

1. KEDA 基础

KEDA 基于 external scaler 支持事件驱动的扩缩容:

apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: redis-scaledobject spec: scaleTargetRef: name: worker-deployment pollingInterval: 30 cooldownPeriod: 300 minReplicaCount: 0 maxReplicaCount: 10 triggers: - type: redis metadata: address: redis:6379 listName: my-list listLength: '5'

2. Kafka Scaler

apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: kafka-scaledobject spec: scaleTargetRef: name: kafka-consumer pollingInterval: 30 cooldownPeriod: 300 minReplicaCount: 0 maxReplicaCount: 10 triggers: - type: kafka metadata: bootstrapServers: my-kafka:9092 consumerGroup: my-group topic: my-topic lagThreshold: '1000'

3. AWS SQS Scaler

apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: sqs-scaledobject spec: scaleTargetRef: name: sqs-worker pollingInterval: 30 cooldownPeriod: 300 minReplicaCount: 0 maxReplicaCount: 20 triggers: - type: aws-sqs metadata: queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/my-queue queueLength: '5' awsRegion: us-east-1

4. 安装 KEDA

# 安装 KEDA kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.12.0/keda-2.12.0.yaml # 验证 kubectl get pods -n keda kubectl get scaledobjects

Cluster Autoscaler

1. Cluster Autoscaler 配置

apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler namespace: kube-system data: balance-similar-node-groups: "true" skip-nodes-with-local-storage: "true" skip-nodes-with-system-pods: "true"

2. 节点自动扩容

# 部署 Cluster Autoscaler(云平台特定) # AWS EKS eksctl utils install cluster-autoscaler --cluster=my-cluster # Azure AKS az aks update --resource-group myResourceGroup --name myAKSCluster --enable-cluster-autoscaler --min-count 1 --max-count 5 --node-count 2 # Google GKE gcloud container clusters update my-cluster --enable-autoscaling --min-nodes 1 --max-nodes 10 --num-nodes 2

实战案例

1. Web 应用自动扩缩容

apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 2 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app image: nginx:latest resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: web-app-service spec: selector: app: web-app ports: - port: 80 targetPort: 80 type: LoadBalancer --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web-app minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 50 periodSeconds: 60 scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 100 periodSeconds: 15

2. 批处理作业自动扩缩容

apiVersion: batch/v1 kind: Job metadata: name: batch-job spec: parallelism: 1 completions: 100 template: spec: containers: - name: worker image: python:3.9 command: - python - -c - | import time import random time.sleep(random.randint(10, 30)) print("Job completed") resources: requests: cpu: 100m memory: 128Mi restartPolicy: OnFailure --- apiVersion: keda.sh/v1alpha1 kind: ScaledJob metadata: name: batch-scaled-job spec: jobTargetRef: parallelism: 1 completions: 100 backoffLimit: 6 pollingInterval: 30 maxReplicaCount: 10 successfulJobsHistoryLimit: 10 failedJobsHistoryLimit: 10 triggers: - type: cpu metadata: type: Utilization value: "80"

3. 零扩缩容(Scale to Zero)

apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: scale-to-zero spec: scaleTargetRef: name: worker-deployment minReplicaCount: 0 # 零副本 maxReplicaCount: 10 cooldownPeriod: 300 # 5 分钟无流量后缩减到 0 triggers: - type: redis metadata: address: redis:6379 listName: tasks listLength: '1'

监控与调试

1. 监控 HPA

# 查看 HPA 状态 kubectl get hpa kubectl describe hpa app-hpa # 查看 HPA 指标 kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods # 监控扩缩容事件 kubectl get events --sort-by='.lastTimestamp'

2. 监控 VPA

# 查看 VPA 推荐 kubectl describe vpa app-vpa kubectl get vpa app-vpa -o jsonpath='{.status.recommendation}' # 查看 VPA 事件 kubectl get events | grep vpa

3. 监控 KEDA

# 查看 ScaledObject 状态 kubectl get scaledobjects kubectl describe scaledobject redis-scaledobject # 查看 KEDA Metrics kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 | jq

最佳实践

1. 资源请求和限制

# 合理设置资源请求 resources: requests: cpu: 100m # 基于监控数据 memory: 128Mi limits: cpu: 500m # 2-3 倍请求值 memory: 512Mi

2. 扩缩容策略

behavior: scaleUp: stabilizationWindowSeconds: 0 # 快速扩容 policies: - type: Percent value: 100 periodSeconds: 15 selectPolicy: Max scaleDown: stabilizationWindowSeconds: 300 # 避免频繁缩容 policies: - type: Percent value: 50 periodSeconds: 60 selectPolicy: Min

3. 多指标策略

# 结合 CPU、内存和自定义指标 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 70 - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "100"

4. 成本优化

# 开发环境:激进扩缩容 spec: minReplicas: 0 maxReplicas: 5 behavior: scaleDown: stabilizationWindowSeconds: 60 # 快速缩容 # 生产环境:保守策略 spec: minReplicas: 3 # 保证最小容量 maxReplicas: 20 behavior: scaleDown: stabilizationWindowSeconds: 300 # 避免频繁缩容

故障排查

1. HPA 无法扩容

# 检查 Metrics Server kubectl get pods -n kube-system -l k8s-app=metrics-server # 检查资源指标 kubectl top pods # 检查 HPA 状态 kubectl describe hpa app-hpa

2. VPA 与 HPA 冲突

# 避免 VPA 和 HPA 同时管理 CPU # VPA 管理 CPU 和内存,HPA 仅管理内存 # 或者使用 VPA 的 Off 模式

3. KEDA Scaler 不工作

# 检查 ScaledObject 配置 kubectl describe scaledobject redis-scaledobject # 检查 KEDA Operator kubectl get pods -n keda # 检查 external metrics kubectl get --raw /apis/external.metrics.k8s.io/v1beta1

总结

Kubernetes 自动扩缩容是云原生应用的关键能力:

HPA:水平扩缩容,基于 CPU、内存、自定义指标
VPA:垂直扩缩容,优化资源请求和限制
KEDA:事件驱动扩缩容,零副本能力
Cluster Autoscaler:节点级扩缩容

通过合理配置和使用这些工具,可以构建弹性、高效、成本优化的 Kubernetes 应用。


发布者: 作者: 转发
评论区 (0)
U