【问题标题】:How to scale Azure's Kubernetes Service (AKS) based on GPU metrics?如何根据 GPU 指标扩展 Azure 的 Kubernetes 服务 (AKS)?
【发布时间】:2020-11-30 16:04:27
【问题描述】:

问题

我正在尝试在我的 AKS 集群上实施 Horizo​​ntal Pod Autoscaler (HPA)。但是,我无法检索我的 HPA 需要扩展的 GPU 指标(由 Azure 自动生成)。

示例

作为参考,请参阅 this example,其中 HPA 基于 targetCPUUtilizationPercentage: 50 进行扩展。也就是说,HPA 将部署更多/更少的 pod,以实现所有 pod 的平均 CPU 利用率目标。理想情况下,我想用 GPU 实现同样的效果。

设置

我部署了一个启用了 Azure Monitor 的 AKS 集群,并且我的节点大小设置为 Standard_NC6_Promo - Azure 的 VM 选项,配备了 Nvidia 的 Tesla K80 GPU。但是,为了利用 GPU,您必须首先将适当的插件安装到您的集群中,如 here 所述。安装此插件后,Azure 会自动收集许多 GPU 指标并将其记录到名为“InsightsMetrics”(see) 的表中。据我所知,指标containerGpuDutyCycle 将最有利于监控 GPU 利用率。

现状

我可以成功查看已安装插件收集的洞察指标,其中一个指标是containerGpuDutyCycle

InsightsMetrics table inside of Logs tab of Kubernetes Service on Azure Portal

现在如何向我的 HPA 公开/提供此指标?

可能的解决方案

我注意到,如果您导航到 AKS 集群的 Metrics 选项卡,您将无法检索这些 GPU 指标。我认为这是因为这些 GPU“指标”在技术上是日志,而不是“官方”指标。但是,azure 确实支持称为 log-based metrics 的东西,其中日志查询的结果可以被视为“官方”指标,但我看不到如何创建自己的基于日志的自定义指标。

此外,Kubernetes supports custom and external metrics 通过他们的 Metrics API,可以从外部来源(例如 Azure 的 Application Insights)检索指标。 Azure 有一个名为 Azure Kubernetes Metrics Adapter 的 Metrics API 实现。也许我需要使用这个将containerGpuDutyCycle 指标公开为外部指标?如果是这样,我如何将指标引用/公开为外部/自定义?

替代解决方案

我主要关心的是公开 HPA 的 GPU 指标。我现在正在使用 Azure 的 Kubernetes Metrics Adapter,因为我认为它会更好地集成到我的 AKS 集群(相同的生态系统)中。但是,它处于 alpha 阶段(尚未准备好生产)。如果有人可以使用替代指标适配器(例如Prometheus)解决我的问题,那仍然会非常有帮助。

非常感谢您对这个问题的任何启发。

【问题讨论】:

标签: kubernetes gpu metrics azure-aks horizontal-pod-autoscaling


【解决方案1】:

我最近(就在本周)设法做到了这一点。我将概述我的解决方案和所有问题,以防万一。

从 AKS 集群开始,我安装了以下组件以收集 GPU 指标:

  1. nvidia-device-plugin - 使 GPU 指标可收集
  2. dcgm-exporter - 显示每个节点上的 GPU 指标的守护程序集
  3. kube-prometheus-stack - 收集并存储 GPU 指标
  4. prometheus-adapter - 将收集的、存储的指标提供给 k8s 指标服务器

AKS 群集带有内置的指标服务器,因此您无需担心这一点。也可以使用已应用的 nvidia-device-plugin 来配置集群,但目前无法通过 terraform (Is it possible to use aks custom headers with the azurerm_kubernetes_cluster resource?),这就是我部署集群的方式。

为了安装所有这些东西,我使用了一个类似于以下的脚本:

helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add gpu-helm-charts https://nvidia.github.io/gpu-monitoring-tools/helm-charts

helm repo update

echo "Installing the NVIDIA device plugin..."
helm install nvdp/nvidia-device-plugin \
--generate-name \
--set migStrategy=mixed \
--version=0.9.0

echo "Installing the Prometheus/Grafana stack..."
helm install prometheus-community/kube-prometheus-stack \
--create-namespace --namespace prometheus \
--generate-name \
--values ./kube-prometheus-stack.values

prometheus_service=$(kubectl get svc -nprometheus -lapp=kube-prometheus-stack-prometheus -ojsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace prometheus \
--set rbac.create=true,prometheus.url=http://${prometheus_service}.prometheus.svc.cluster.local,prometheus.port=9090

helm install gpu-helm-charts/dcgm-exporter \
--generate-name

实际上,我在撒谎dcgm-exporter。我遇到了一个问题(我的第一个“陷阱”),dcgm-exporter 没有及时响应活动请求,并且一直进入CrashLoopBackoff 状态(https://github.com/NVIDIA/gpu-monitoring-tools/issues/120)。为了解决这个问题,我创建了自己的dcgm-exporter k8s 配置(通过从这里获取细节并稍微修改它们:https://github.com/NVIDIA/gpu-monitoring-tools)并应用它。 在此过程中,我遇到了第二个“陷阱”,即在最新的dcgm-exporter 图像中,他们删除了一些 GPU 指标,例如DCGM_FI_DEV_GPU_UTIL,主要是因为收集这些指标需要大量资源(请参阅https://github.com/NVIDIA/gpu-monitoring-tools/issues/143)。如果您想重新启用它们,请确保您运行 dcgm-exporter 并将参数设置为:["-f", "/etc/dcgm-exporter/dcp-metrics-included.csv"] 或者您可以创建自己的图像并提供自己的指标列表,这就是我使用此 Dockerfile 所做的:

FROM nvcr.io/nvidia/k8s/dcgm-exporter:2.1.4-2.3.1-ubuntu18.04

RUN sed -i -e '/^# DCGM_FI_DEV_GPU_UTIL.*/s/^#\ //' /etc/dcgm-exporter/default-counters.csv

ENTRYPOINT ["/usr/local/dcgm/dcgm-exporter-entrypoint.sh"]

您可以从上面的脚本中看到的另一件事是,我还使用了自己的 Prometheus helm 图表值文件。我按照 nvidia 网站 (https://docs.nvidia.com/datacenter/cloud-native/kubernetes/dcgme2e.html) 的说明进行操作,但在 additionalScrapeConfig 中找到了我的第三个“陷阱”。

我了解到,在最终部署中,HPA 必须与它正在扩展的服务(由 targetRef 标识)位于相同的命名空间中,否则它无法找到它来扩展它,你可能已经知道了。

但同样重要的是dcgm-metrics Service 也必须在同一个命名空间中,否则 HPA 无法找到它需要扩展的指标经过。 因此,我更改了 additionalScrapeConfig 以定位相关的命名空间。我确信有一种方法可以使用 additionalScrapeConfig.relabel_configs 部分,使您能够将 dcgm-exporter 保留在不同的命名空间中,并且仍然让 HPA 找到指标,但我还没有时间学习那个巫术​​。

完成所有这些后,我可以检查 DCGM 指标是否可供 kube 指标服务器使用:

$ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq -r . | grep DCGM_FI_DEV_GPU_UTIL

在结果列表中,您真的希望看到 services 条目,如下所示:

"name": "jobs.batch/DCGM_FI_DEV_GPU_UTIL",
"name": "namespaces/DCGM_FI_DEV_GPU_UTIL",
"name": "services/DCGM_FI_DEV_GPU_UTIL",
"name": "pods/DCGM_FI_DEV_GPU_UTIL",

如果您不这样做,这可能意味着您使用的 dcgm-exporter 部署缺少 ServiceAccount 组件,并且 HPA 仍然无法工作。

最后,我这样写了我的 HPA:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
  namespace: my-namespace
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: X
  maxReplicas: Y
...
  metrics:
  - type: Object
    object:
      metricName: DCGM_FI_DEV_GPU_UTIL
      targetValue: 80
      target:
        kind: Service
        name: dcgm-exporter

一切都奏效了。

我希望这会有所帮助!我花了很长时间尝试人们在咨询公司博客、媒体帖子等上展示的不同方法,然后发现编写这些文章的人已经对您的部署做出了假设,这会影响您真正需要了解的细节(例如:命名空间问题) .

【讨论】:

  • 嘿@ndtreviv,感谢您提供的超级有用的答案!我正在尝试使用 GKE 集群来实现这一点。我设法导出了 DCGM 指标,但是当尝试从我的 HPA 访问它时,我遇到了以下问题:unable to get metric external.googleapis.com|prometheus|DCGM_FI_DEV_GPU_UTIL: Service on default dcgm-exporter/unable to fetch metrics from custom metrics API: Operation: "Get namespaced metric by name for resource \"services\"" is not implemented 知道可能出了什么问题吗?
  • @Jules 您能否确认您创建了 ServiceAccount?似乎它可能丢失了,或者您的 ServiceAccount 配置以某种方式出错。重新检查一下我所说的真的很想看到一个服务条目。听起来你的好像不见了?
  • 是的,services 部分实际上丢失了。它只显示"name": "*/external.googleapis.com|prometheus|DCGM_FI_DEV_GPU_UTIL"。我已经完成了几次设置,不知道出了什么问题...会再试一次,让你知道! :)
  • @Jules 看起来它已作为您设置的外部指标启用。恐怕我不能 100% 确定如何使用它,但第一个猜测是更改 HPA 以查找具有正确名称的外部指标。
猜你喜欢
  • 2022-01-14
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 2020-09-16
  • 1970-01-01
  • 2021-05-08
相关资源
最近更新 更多