3

问题

我正在尝试在我的 AKS 集群上实现一个 Horizo​​ntal Pod Autoscaler (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)解决我的问题,那仍然会非常有帮助。

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

4

1 回答 1

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 (Is it possible to use aks custom headers with the 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

事实上,我在撒谎dcgm-exporter。我遇到了一个问题(我的第一个“陷阱”),它dcgm-exporter没有及时响应活动请求,并且一直进入CrashLoopBackoff状态(https://github.com/NVIDIA/gpu-monitoring-tools/issues/120) . 为了解决这个问题,我创建了自己的dcgm-exporterk8s 配置(通过从这里获取细节并稍微修改它们:https ://github.com/NVIDIA/gpu-monitoring-tools )并应用它。在此过程中,我遇到了第二个“陷阱”,即在最新的图像中,他们删除了一些GPU指标dcgm-exporter,例如-监控工具/问题/143DCGM_FI_DEV_GPU_UTIL)。如果要重新启用它们,请确保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

这一切都奏效了。

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

于 2021-03-25T11:03:59.890 回答