如何根据 GPU 指标扩展 Azure 的 Kubernetes 服务 (AKS)?

Kar*_*-FS 3 metrics gpu kubernetes azure-aks horizontal-pod-autoscaling

问题

我正在尝试在我的 AKS 集群上实施水平 Pod 自动缩放器 (HPA)。但是,我无法检索 HPA 扩展所需的 GPU 指标(由 Azure 自动生成)。

例子

作为参考,请参阅此示例,其中 HPA 基于targetCPUUtilizationPercentage: 50. 也就是说,HPA 将部署更多/更少的 Pod,以实现所有 Pod 的平均 CPU 利用率的目标。理想情况下,我想用 GPU 实现相同的目标。

设置

我已经部署了一个启用了 Azure Monitor 的 AKS 集群,并且我的节点大小设置为Standard_NC6_Promo- Azure 的 VM 选项,它配备了 Nvidia 的 Tesla K80 GPU。然而,为了利用GPU,必须先安装相应的插件安装到您的群集,如解释在这里。安装此插件后,Azure 会自动收集大量 GPU 指标并记录到名为“InsightsMetrics”的表中(请参阅参考资料)。据我所知,该指标containerGpuDutyCycle最有利于监控 GPU 利用率。

现在的情况

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

Azure 门户上 Kubernetes 服务的日志选项卡内的 InsightsMetrics 表

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

可能的解决方案

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

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

替代解决方案

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

非常感谢您对这个问题的任何了解。

ndt*_*viv 5

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

从 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(是否可以将 aks 自定义标头与 azurerm_kubernetes_cluster 资源一起使用?),这就是我部署集群的方式。

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

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
Run Code Online (Sandbox Code Playgroud)

事实上,我在撒谎dcgm-exporter。我遇到了一个问题(我的第一个“陷阱”)dcgm-exporter没有及时响应活性请求,并且一直进入CrashLoopBackoff状态(https://github.com/NVIDIA/gpu-monitoring-tools/issues/120) . 为了解决这个问题,我创建了自己的dcgm-exporterk8s 配置(通过从这里获取详细信息并稍微修改它们:https : //github.com/NVIDIA/gpu-monitoring-tools)并应用它。在这样做时,我遇到了我的第二个“问题”,即在最新的dcgm-exporter图像中,他们删除了一些 GPU 指标,例如DCGM_FI_DEV_GPU_UTIL,主要是因为这些指标需要大量资源来收集(请参阅https://github.com/NVIDIA/gpu -监控工具/问题/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"]
Run Code Online (Sandbox Code Playgroud)

您可以从上述脚本中看到的另一件事是,我还使用了自己的 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
Run Code Online (Sandbox Code Playgroud)

在结果列表中,您确实希望看到一个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",
Run Code Online (Sandbox Code Playgroud)

如果不这样做,则可能意味着您使用的 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
Run Code Online (Sandbox Code Playgroud)

这一切都奏效了。

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