Horizo​​ntalPodAutoscaler:用于在 GKE 中部署自定义指标 Stackdriver 适配器的已发布文档是否完整且正确?

HorizontalPodAutoscaler: Is the published documentation for deploying the custom metrics stackdriver adapter in GKE complete and correct?

Google 发布了使用自定义指标驱动 HorizontalPodAutoscaler here 的教程,本教程包含以下说明:

  1. 使用 Kubernetes 清单将自定义指标适配器部署到 custom-metrics 命名空间。
  2. 正在部署虚拟应用程序以生成指标。
  3. 配置 HPA 以使用自定义指标。

我们正在部署到没有任何特殊 VPC 规则的默认集群中,我们大致遵循了教程的指导,但有一些例外:

我们正在将 HPA 配置为根据属于有状态集的所有 pods 的派生指标的平均值进行扩展(HPA 具有类型为 Pods 的指标条目) .但是,HPA 无法读取我们的派生指标。我们看到此错误消息:

failed to get object metric value: unable to get metric xxx_scaling_metric: no metrics returned from custom metrics API

更新

我们看到了 DNS 错误,但这些显然是误报,可能在集群启动时出现在日志中。

我们使用命令行选项 --v=5 重新启动了 Stackdriver 指标适配器,以进行更详细的调试。我们看到这样的日志条目:

I0123 20:23:08.069406       1 wrap.go:47] GET /apis/custom.metrics.k8s.io/v1beta1/namespaces/defaults/pods/%2A/xxx_scaling_metric: (56.16652ms) 200 [kubectl/v1.13.11 (darwin/amd64) kubernetes/2e298c7 10.44.1.1:36286]
I0123 20:23:12.997569       1 translator.go:570] Metric 'xxx_scaling_metric' not found for pod 'xxx-0'
I0123 20:23:12.997775       1 wrap.go:47] GET /apis/custom.metrics.k8s.io/v1beta2/namespaces/default/pods/%2A/xxx_scaling_metric?labelSelector=app%3Dxxx: (98.101205ms) 200 [kube-controller-manager/v1.13.11 (linux/amd64) kubernetes/56d8986/system:serviceaccount:kube-system:horizontal-pod-autoscaler 10.44.1.1:36286]

所以它 在我们看来 好像 HPA 正在对基于 pods 的自定义指标进行正确的查询。如果我们询问自定义指标 API 它有什么数据,并使用 jq 过滤我们感兴趣的指标,我们会看到:

{"kind":"MetricValueList",
 "apiVersion":"custom.metrics.k8s.io/v1beta1",
 "metadata: {"selfLink":"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/xxx_scaling_metric"},
 "items":[]}

项目数组为空令人不安。同样,我们可以在指标资源管理器中看到数据,所以我们想知道发布我们的缩放指标的 CronJob 应用程序是否提供了正确的字段,以便将数据保存在 Stackdriver 中或通过指标适配器公开。

我们在 CronJob 中发布的时间序列的 resource.labels 地图的价值如下:

{'cluster_name': 'test-gke', 
 'zone': 'us-central1-f', 
 'project_id': 'my-project-1234', 
 'container_name': '', 
 'instance_id': '1234567890123456789',
 'pod_id': 'xxx-0', 
 'namespace_id': 'default'}

我们终于解决了这个问题。我们的 CronJob 发布了我们想要使用的派生指标,它从从 Stackdriver 日志中提取的另外两个指标获取原始数据,并计算一个新值并将其发布回 Stackdriver。

我们在发布派生指标时使用了从这些指标中看到的资源标签。我们正在阅读的 "input" Stackdriver 指标中的 POD_ID 资源标签值是 pod 的名称。但是,位于 gcr.io/google-containers/custom-metrics-stackdriver-adapter:v0.10.0 的 stackdriver 自定义指标适配器正在枚举命名空间中的 pods 并要求 stackdriver 提供与 pods 的 UID 关联的数据,而不是它们的名称。 (阅读适配器的源代码来解决这个问题...)

因此,我们的 CronJob 现在构建一个 pod 名称到 pod UID 的映射(这要求它具有 RBAC pod 列表并获取角色),并发布我们用于 HPA 的派生指标,其中 POD_ID 设置为pod 的 UID 而不是它的名称。

已发布的 HPA 自定义指标示例(如 this)起作用的原因是它们使用向下 API 获取 pod 的 UID,并将该值提供为 "POD_ID".回想起来,如果我们查看 "dummy" 指标导出器如何获得其 pod id 值,那应该是显而易见的,但肯定有一些示例(如 Stackdriver 日志指标)其中 POD_ID 最终成为名称而不是 UID。