Kubernetes HPA 为自定义指标获取错误的当前值

Posted

技术标签:

【中文标题】Kubernetes HPA 为自定义指标获取错误的当前值【英文标题】:Kubernetes HPA gets wrong current value for a custom metric 【发布时间】:2018-09-23 19:31:17 【问题描述】:

HPA 状态在实际度量值低于100/500 的情况下显示132500m / 500(根据Prometheus)。

$ kubectl get hpa -n frontend --context testing
NAME       REFERENCE              TARGETS                               MINPODS   MAXPODS   REPLICAS   AGE
frontend   Deployment/streaming   50237440 / 629145600, 132500m / 500   2         5         2          4d

HPA 清单是:

---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: frontend
  namespace: streaming
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: streaming
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metricName: redis_memory_used_rss_bytes
      targetAverageValue: 629145600
  - type: Pods
    pods:
      metricName: redis_db_keys
      targetAverageValue: 500

它应该打印正常的结果,例如:

$ kubectl get hpa -n streaming --context streaming-eu
NAME       REFERENCE              TARGETS                               MINPODS   MAXPODS   REPLICAS   AGE
frontend   Deployment/streaming   50237440 / 629145600, 87 / 500   2         5         2          4d

问题在于132500m 值是错误的(Prometheus 查询报告了正常值)。由于HPA 没有按该指标进行扩展,所以我认为它的价值有所不同。

使用oliver006/redis_exporter 和它的指标作为自定义Pod 指标与HPA 来重现此问题。

Kubernetes 版本

Client Version: version.InfoMajor:"1", Minor:"8", GitVersion:"v1.8.6", GitCommit:"6260bb08c46c31eea6cb538b34a9ceb3e406689c", GitTreeState:"clean", BuildDate:"2017-12-21T06:34:11Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"`
Server Version: version.InfoMajor:"1", Minor:"9+", GitVersion:"v1.9.4-gke.1", GitCommit:"10e47a740d0036a4964280bd663c8500da58e3aa", GitTreeState:"clean", BuildDate:"2018-03-13T18:00:36Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"

云提供商

GKE 1.9.4

【问题讨论】:

您的集群中是否有任何其他 Redis 缓存,除了您想用作扩展指标来源的缓存? 不,只是它的这两个 pod 在单独的命名空间中 【参考方案1】:

我认为这是一个度量转换问题。

这是来自相关问题的贡献者的一个很好的comment,但它是关于http_requests 指标的:

如果您查看 Prometheus 适配器的文档,您会看到所有累积(计数器)指标都转换为速率指标,因为 HPA 的算法从根本上与直接缩放累积指标(直接缩放累积指标)不兼容一般没有多大意义)。

在您的情况下,您的 http_requests_total 正在转换为 http_requests,因此在使用 Prometheus 适配器时,它将始终显示为来自度量 API 的毫请求。

因此,在您的情况下,它返回的内容类似于 132500 毫秒。只需将值除以 1000,即可得到正确的平均值。

【讨论】:

感谢您的建议,伙计,这很有道理。但是,有一些事情让我感到困扰:它不时显示实际的度量值,所以如果它试图将它转换为毫记录,这很奇怪。你怎么看? 我只能猜测这是转换结合平均值计算的神器。 这是正确的(来源:我写了很多有问题的代码)。对于大多数可能需要小数位的数值,Kubernetes 使用一种称为Quantity 的特殊类型。它不会以小数形式显示,而是以 SI 后缀显示。例如,1.5 变为 1500m。当 Kubernetes 显示数量时,如果有小数点,它将倾向于使用毫单位,否则将使用普通单位。因此,如果必须在点上显示 500,它只会显示 500,但如果是 500.5,它将显示 500500m。它们的意思是一样的——只是显示问题。 @DirectXMan12 再次感谢您,我会标记为正确的。

以上是关于Kubernetes HPA 为自定义指标获取错误的当前值的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Kubernetes HPA 转换自定义指标?

Kubernetes HPA(带有自定义指标)扩展策略

在 Kubernetes 中使用多个自定义指标适配器

具有自定义指标的 HPA

HPA 缩减 kubernetes pod

具有 2 个或更多指标的 kubernetes HPA 的行为如何——尤其是副本数计算?