水平 Pod 自动扩缩容 (HPA)
OpenTelemetry Operator 管理的 Collector 内置支持水平 Pod 自动扩缩容(Horizontal Pod Autoscaling,HPA)。HPA 可以根据 CPU 和内存使用率自动增加或减少 Collector Pod 的副本数,确保 Collector 能够根据负载自动调整规模,提高资源利用率和系统稳定性。
概述
什么是 HPA?
水平 Pod 自动扩缩容(HPA)是 Kubernetes 的一个功能,它可以根据观察到的 CPU 使用率、内存使用率或其他自定义指标,自动增加或减少 Pod 的副本数。HPA 确保应用能够根据实际负载自动调整规模,既不会因为资源不足而影响性能,也不会因为资源浪费而增加成本。
HPA 的工作原理
┌─────────────────────────────────────────────────────────┐│ HPA Controller ││ ┌─────────────────────────────────────────────────┐ ││ │ 1. 查询 Metrics Server 获取当前指标 │ ││ │ 2. 计算期望副本数 │ ││ │ 3. 更新 Deployment/StatefulSet 的副本数 │ ││ └─────────────────────────────────────────────────┘ │└────────────────────┬──────────────────────────────────┘│▼┌─────────────────────────────────────────────────────────┐│ Metrics Server ││ ┌─────────────────────────────────────────────────┐ ││ │ 收集 Pod 的 CPU 和内存使用率 │ ││ │ 提供 metrics.k8s.io API │ ││ └─────────────────────────────────────────────────┘ │└────────────────────┬──────────────────────────────────┘│▼┌─────────────────────────────────────────────────────────┐│ Collector Pods ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ ││ │ CPU: 60% │ │ CPU: 55% │ │ CPU: 58% │ ││ └──────────┘ └──────────┘ └──────────┘ │└─────────────────────────────────────────────────────────┘
HPA 的优势
- 自动化:无需手动调整副本数,系统自动响应负载变化
- 资源优化:根据实际需求动态调整资源,避免资源浪费
- 高可用性:在负载增加时自动扩容,确保服务可用性
- 成本控制:在负载降低时自动缩容,降低资源成本
- 简化运维:减少人工干预,降低运维复杂度
Operator 的 HPA 支持
OpenTelemetry Operator 内置了 HPA 功能,这意味着:
- 无需手动创建 HPA:Operator 会自动创建和管理 HPA 资源
- 统一配置:在 OpenTelemetryCollector 资源中配置 HPA 参数
- 自动管理:Operator 负责 HPA 的创建、更新和删除
前置要求
在使用 HPA 之前,需要确保满足以下要求:
Metrics Server
HPA 需要 Metrics Server 来获取 Pod 的 CPU 和内存使用率。Metrics Server 是 Kubernetes 集群的组件,用于收集和提供资源使用指标。
检查 Metrics Server
# 检查 Metrics Server 是否已安装kubectl get pods -n kube-system | grep metrics-server# 检查 Metrics Server API 是否可用kubectl top nodeskubectl top pods
如果命令执行成功,说明 Metrics Server 已安装并正常工作。
不同云平台的 Metrics Server 状态
Google Kubernetes Engine (GKE):
- Metrics Server 在集群创建时自动安装
- 无需手动安装
Azure Kubernetes Service (AKS):
- Metrics Server 在集群创建时自动安装
- 无需手动安装
Amazon Elastic Kubernetes Service (EKS):
- 默认不安装 Metrics Server
- 需要手动安装
本地 Kubernetes 集群(如 Minikube、KinD、k0s):
- 需要手动安装 Metrics Server
安装 Metrics Server
如果您的集群没有 Metrics Server,可以按以下步骤安装:
在 EKS 上安装:
# 下载 Metrics Server 清单curl -L https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -o metrics-server.yaml# 修改配置以支持 EKS(如果需要)# 在 args 中添加:--kubelet-insecure-tls# 应用配置kubectl apply -f metrics-server.yaml# 验证安装kubectl get pods -n kube-system | grep metrics-server
在本地集群安装:
# Minikubeminikube addons enable metrics-server# KinD 或其他集群kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
验证 Metrics Server:
# 等待 Metrics Server 就绪kubectl wait --for=condition=ready pod -l k8s-app=metrics-server -n kube-system --timeout=300s# 测试 Metrics APIkubectl top nodeskubectl top pods --all-namespaces
部署模式要求
HPA 只适用于 Deployment 和 StatefulSet 模式。如果 Collector 使用 DaemonSet 模式,则不支持 HPA。
确保 Collector 的 spec.mode 设置为 deployment 或 statefulset:
spec:mode: deployment # 或 statefulset
配置资源请求和限制
在配置 HPA 之前,必须先为 Collector 配置资源请求(requests)和限制(limits)。HPA 使用这些值来计算资源使用率。
为什么需要资源请求和限制?
- 资源请求(requests):Kubernetes 调度器使用此值来确保 Pod 有足够的资源运行
- 资源限制(limits):Kubernetes 使用此值来限制 Pod 的最大资源使用
- HPA 计算:HPA 使用资源使用率(实际使用量 / 请求量)来决定是否需要扩缩容
配置示例
基本配置
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolspec:resources:limits:cpu: 100mmemory: 128Mirequests:cpu: 100mmemory: 64Mi
配置说明
limits(限制):
cpu: 100m:最大 CPU 使用量为 100 millicores(0.1 核心)memory: 128Mi:最大内存使用量为 128 mebibytes(约 134 MB)
requests(请求):
cpu: 100m:保证的 CPU 资源为 100 millicoresmemory: 64Mi:保证的内存资源为 64 mebibytes(约 67 MB)
资源单位说明
CPU 单位:
1= 1 个 CPU 核心1000m= 1 个 CPU 核心500m= 0.5 个 CPU 核心100m= 0.1 个 CPU 核心
内存单位:
1Gi= 1024 MiB = 1,073,741,824 字节1Mi= 1024 KiB = 1,048,576 字节128Mi= 134,217,728 字节
资源配置建议
小型部署
适用于低流量场景:
resources:limits:cpu: 500mmemory: 512Mirequests:cpu: 200mmemory: 256Mi
中型部署
适用于中等流量场景:
resources:limits:cpu: 2000mmemory: 2Girequests:cpu: 500mmemory: 512Mi
大型部署
适用于高流量场景:
resources:limits:cpu: 4000mmemory: 4Girequests:cpu: 1000mmemory: 1Gi
资源配置注意事项
requests 和 limits 的关系:
requests应该小于或等于limits- HPA 使用
requests作为基准计算使用率
CPU 配置:
- CPU 是可压缩资源,可以超量分配
- 建议
requests和limits相同,避免 CPU 节流
内存配置:
- 内存是不可压缩资源,不能超量分配
limits应该大于requests,为突发流量留出空间
实际需求:
- 根据实际负载调整资源配置
- 监控 Collector 的实际资源使用情况
- 定期调整配置以优化资源利用
配置自动扩缩容规则
配置资源请求和限制后,可以配置 HPA 的自动扩缩容规则。
基本配置
在 OpenTelemetryCollector 资源中添加 autoscaler 配置:
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolspec:autoscaler:minReplicas: 1maxReplicas: 3targetCPUUtilization: 50targetMemoryUtilization: 60
配置参数说明
minReplicas(最小副本数)
- 类型:整数
- 默认值:1
- 说明:Collector 的最小副本数,即使负载很低也不会低于此值
- 建议:生产环境建议设置为 2 或更高,确保高可用性
maxReplicas(最大副本数)
- 类型:整数
- 默认值:无(必须指定)
- 说明:Collector 的最大副本数,即使负载很高也不会超过此值
- 建议:根据集群容量和预期负载设置合理值
targetCPUUtilization(目标 CPU 使用率)
- 类型:整数(百分比)
- 默认值:无(必须指定)
- 说明:目标 CPU 使用率,HPA 会尝试将平均 CPU 使用率维持在此值
- 单位:百分比(例如,50 表示 50%)
- 建议:通常设置为 50-80%
targetMemoryUtilization(目标内存使用率)
- 类型:整数(百分比)
- 默认值:无(必须指定)
- 说明:目标内存使用率,HPA 会尝试将平均内存使用率维持在此值
- 单位:百分比(例如,60 表示 60%)
- 建议:通常设置为 60-80%
配置示例
示例 1:仅基于 CPU
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolspec:mode: deploymentresources:limits:cpu: 1000mmemory: 512Mirequests:cpu: 500mmemory: 256Miautoscaler:minReplicas: 2maxReplicas: 10targetCPUUtilization: 70
示例 2:基于 CPU 和内存
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolspec:mode: statefulsetresources:limits:cpu: 2000mmemory: 1Girequests:cpu: 1000mmemory: 512Miautoscaler:minReplicas: 2maxReplicas: 10targetCPUUtilization: 70targetMemoryUtilization: 80
示例 3:高可用配置
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolspec:mode: deploymentresources:limits:cpu: 2000mmemory: 2Girequests:cpu: 1000mmemory: 1Giautoscaler:minReplicas: 3maxReplicas: 20targetCPUUtilization: 60targetMemoryUtilization: 70
扩缩容行为
HPA 会根据以下规则进行扩缩容:
计算当前使用率:
- CPU 使用率 = (当前 CPU 使用量 / CPU 请求量) × 100%
- 内存使用率 = (当前内存使用量 / 内存请求量) × 100%
计算期望副本数:
- 期望副本数 = (当前副本数 × 当前使用率) / 目标使用率
- 如果同时配置了 CPU 和内存,取两者中的较大值
应用限制:
- 如果期望副本数 < minReplicas,设置为 minReplicas
- 如果期望副本数 > maxReplicas,设置为 maxReplicas
执行扩缩容:
- 更新 Deployment 或 StatefulSet 的副本数
- 等待 Pod 创建或删除完成
完整配置示例
以下是一个完整的 OpenTelemetryCollector 配置示例,包含 HPA 配置:
apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata:name: otelcolnamespace: opentelemetryspec:mode: statefulsetimage: otel/opentelemetry-collector-contrib:v0.100.0serviceAccount: otelcontribcol# 资源请求和限制resources:limits:cpu: 2000mmemory: 2Girequests:cpu: 1000mmemory: 1Gi# HPA 配置autoscaler:minReplicas: 2maxReplicas: 10targetCPUUtilization: 70targetMemoryUtilization: 80# Collector 配置config: |receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318processors:memory_limiter:check_interval: 1slimit_percentage: 75spike_limit_percentage: 15batch:timeout: 1ssend_batch_size: 1024exporters:otlp:endpoint: uptrace-grpc.yodao.cn:4317tls:insecure: falseservice:pipelines:traces:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]metrics:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]logs:receivers: [otlp]processors: [memory_limiter, batch]exporters: [otlp]
应用配置
保存配置到文件(例如 collector-with-hpa.yaml),然后应用:
# 应用配置kubectl apply -f collector-with-hpa.yaml# 检查 Collector 状态kubectl get opentelemetrycollector otelcol -n opentelemetry# 检查 HPA 是否创建kubectl get hpa -n opentelemetry
验证 HPA
配置 HPA 后,需要验证 HPA 是否正常工作。
检查 HPA 资源
# 查看 HPA 资源kubectl get hpa -n <namespace># 预期输出示例:# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE# otelcol-collector OpenTelemetryCollector/otelcol memory: 68%/80%, cpu: 37%/70% 2 10 3 5m
查看 HPA 详细信息
# 查看 HPA 详细信息kubectl describe hpa <hpa-name> -n <namespace>
预期输出示例:
Name: otelcol-collectorNamespace: opentelemetryLabels: app.kubernetes.io/component=opentelemetry-collectorapp.kubernetes.io/instance=opentelemetry.otelcolapp.kubernetes.io/managed-by=opentelemetry-operatorapp.kubernetes.io/name=otelcol-collectorapp.kubernetes.io/part-of=opentelemetryAnnotations: <none>CreationTimestamp: Mon, 02 Jun 2025 17:23:52 +0000Reference: OpenTelemetryCollector/otelcolMetrics: ( current / target )resource memory on pods (as a percentage of request): 71% (95779498666m) / 80%resource cpu on pods (as a percentage of request): 37% (37m) / 70%Min replicas: 2Max replicas: 10OpenTelemetryCollector pods: 3 current / 3 desiredConditions:Type Status Reason Message---- ------ ------ -------AbleToScale True ReadyForNewScale recommended size matches current sizeScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from memory resource utilization (percentage of request)ScalingLimited False DesiredWithinRange the desired replica count is within the acceptable rangeEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal SuccessfulRescale 2m horizontal-pod-autoscaler New size: 2; reason: memory resource utilization (percentage of request) above targetNormal SuccessfulRescale 1m horizontal-pod-autoscaler New size: 3; reason: memory resource utilization (percentage of request) above target
检查 Pod 副本数
# 查看 Collector Pod 数量kubectl get pods -l app.kubernetes.io/name=opentelemetry-collector -n <namespace># 查看 Deployment 或 StatefulSet 的副本数kubectl get deployment -n <namespace> | grep collector# 或kubectl get statefulset -n <namespace> | grep collector
监控 HPA 行为
实时监控
# 持续监控 HPA 状态watch kubectl get hpa -n <namespace># 持续监控 Pod 数量watch kubectl get pods -l app.kubernetes.io/name=opentelemetry-collector -n <namespace>
查看 HPA 事件
# 查看 HPA 事件kubectl describe hpa <hpa-name> -n <namespace> | grep Events -A 10
测试扩缩容
增加负载测试扩容
可以通过增加发送到 Collector 的数据量来测试扩容:
# 使用负载生成工具增加数据量# 观察 HPA 是否自动增加副本数watch kubectl get hpa -n <namespace>
减少负载测试缩容
停止负载生成,观察 HPA 是否自动减少副本数:
# 停止负载生成# 等待一段时间(通常几分钟)# 观察 HPA 是否自动减少副本数watch kubectl get hpa -n <namespace>
最佳实践
1. 合理设置最小副本数
- 生产环境:建议设置为 2 或更高,确保高可用性
- 开发/测试环境:可以设置为 1
autoscaler:minReplicas: 2 # 生产环境# minReplicas: 1 # 开发/测试环境
2. 合理设置最大副本数
- 根据集群容量和预期负载设置
- 考虑成本因素
- 预留一定的缓冲空间
autoscaler:maxReplicas: 10 # 根据实际需求调整
3. 合理设置目标使用率
CPU 使用率:通常设置为 50-80%
- 较低的值(50-60%)提供更多缓冲,但可能增加成本
- 较高的值(70-80%)提高资源利用率,但可能影响性能
内存使用率:通常设置为 60-80%
- 内存是不可压缩资源,建议设置较低的值
autoscaler:targetCPUUtilization: 70targetMemoryUtilization: 75
4. 同时监控 CPU 和内存
建议同时配置 CPU 和内存目标使用率,HPA 会取两者中的较大值:
autoscaler:targetCPUUtilization: 70targetMemoryUtilization: 80
5. 合理配置资源请求
- requests 应该反映 Collector 的正常负载
- limits 应该为突发流量留出空间
- HPA 使用
requests作为基准,因此requests的设置很重要
resources:limits:cpu: 2000mmemory: 2Girequests:cpu: 1000m # 正常负载memory: 1Gi # 正常负载
6. 监控 HPA 行为
定期检查 HPA 的行为:
- 扩缩容频率是否合理
- 副本数是否在预期范围内
- 是否有频繁的扩缩容(抖动)
7. 使用 StatefulSet 模式
对于需要持久化存储或有序部署的场景,使用 StatefulSet 模式:
spec:mode: statefulset
8. 考虑扩缩容延迟
HPA 有一定的延迟:
- 指标收集延迟:Metrics Server 收集指标需要时间
- 决策延迟:HPA 需要一定时间来决定是否扩缩容
- Pod 创建/删除延迟:Pod 的创建和删除需要时间
因此,HPA 更适合处理逐渐变化的负载,而不是突发流量。
常见问题
1. HPA 不工作?
检查步骤:
# 1. 检查 Metrics Serverkubectl get pods -n kube-system | grep metrics-serverkubectl top nodes# 2. 检查 HPA 资源kubectl get hpa -n <namespace># 3. 检查 HPA 详细信息kubectl describe hpa <hpa-name> -n <namespace># 4. 检查 Collector 资源请求和限制kubectl get opentelemetrycollector <name> -o yaml | grep -A 10 resources# 5. 检查 Collector 部署模式kubectl get opentelemetrycollector <name> -o yaml | grep mode
常见原因:
- Metrics Server 未安装或未正常工作
- 资源请求和限制未配置
- 部署模式不是 deployment 或 statefulset
- HPA 配置错误
2. HPA 显示 "unknown" 状态?
可能原因:
- Metrics Server 未正常工作
- Pod 刚创建,还没有指标数据
解决方法:
# 检查 Metrics Serverkubectl get pods -n kube-system | grep metrics-serverkubectl logs -n kube-system -l k8s-app=metrics-server# 等待一段时间后再次检查kubectl get hpa -n <namespace>
3. HPA 频繁扩缩容(抖动)?
可能原因:
- 目标使用率设置不合理
- 负载波动较大
- 资源请求设置不合理
解决方法:
- 调整目标使用率,提供更多缓冲
- 增加资源请求,减少使用率波动
- 考虑使用自定义指标或外部指标
4. HPA 不缩容?
可能原因:
- 最小副本数设置过高
- 实际使用率仍然高于目标
- HPA 有延迟
解决方法:
# 检查当前使用率kubectl describe hpa <hpa-name> -n <namespace># 检查最小副本数kubectl get hpa <hpa-name> -n <namespace> -o yaml | grep minReplicas
5. 如何禁用 HPA?
删除 autoscaler 配置或设置为空:
spec:# autoscaler: {} # 注释掉或删除
然后手动设置副本数:
spec:replicas: 3
6. HPA 支持自定义指标吗?
当前 Operator 的 HPA 配置只支持 CPU 和内存指标。如果需要使用自定义指标,需要:
- 安装 Prometheus Adapter 或其他指标适配器
- 手动创建 HPA 资源(不使用 Operator 的 autoscaler 配置)
7. HPA 扩缩容速度如何?
HPA 的扩缩容速度取决于:
- Metrics Server 的指标收集间隔(通常 15-30 秒)
- HPA 的评估间隔(通常 15 秒)
- Pod 的创建/删除时间(通常 30 秒到几分钟)
总体而言,从负载变化到完成扩缩容,通常需要 1-5 分钟。
下一步
- Operator 概述 - 了解 Operator 的基本概念
- 自动注入 - 了解自动注入功能
- Target Allocator - 使用 Target Allocator
- 故障排查 - 解决 HPA 相关问题