背景

由 k8s HAP 主要支持CPU, Memory自动伸缩,支持自定义标签流程比较复杂, 无法使用时序数据库运算语法,无法满足模型弹性伸缩要求。

KEDA 允许对事件驱动的 Kubernetes 工作负载进行细粒度的自动缩放(包括到/从零)。KEDA 作为 Kubernetes 指标服务器,允许用户使用专用的 Kubernetes 自定义资源定义来定义自动缩放规则。Keda支持主流时序数据库,而且支持聚合,运算语句。尝试通过keda框架关联GPU伸缩。

目前 k8s cadvisor 没有 GPU方面监控。需要补全GPU监控,而且可以提供GPU和POD关联上。

GPU 指标量收集

指标收集器安装

指标收集器使用NVIDIA/dcgm-exporter, 可以参考页面NVIDIA/dcgm-exporter, 安装通过 k8s yaml 安装
dcgm-exporter.yaml

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: "dcgm-exporter"
  5. namespace: monitoring
  6. labels:
  7. app.kubernetes.io/name: "dcgm-exporter"
  8. app.kubernetes.io/version: "2.4.0"
  9. spec:
  10. updateStrategy:
  11. type: RollingUpdate
  12. selector:
  13. matchLabels:
  14. app.kubernetes.io/name: "dcgm-exporter"
  15. app.kubernetes.io/version: "2.4.0"
  16. template:
  17. metadata:
  18. labels:
  19. app.kubernetes.io/name: "dcgm-exporter"
  20. app.kubernetes.io/version: "2.4.0"
  21. name: "dcgm-exporter"
  22. spec:
  23. nodeSelector:
  24. classify: nvidia-gpu # 限制在nvdia-gpu标签机器运行
  25. containers:
  26. - image: "nvcr.io/nvidia/k8s/dcgm-exporter:2.2.9-2.4.0-ubuntu18.04"
  27. env:
  28. - name: "DCGM_EXPORTER_LISTEN"
  29. value: ":9400"
  30. - name: "DCGM_EXPORTER_KUBERNETES"
  31. value: "true"
  32. name: "dcgm-exporter"
  33. ports:
  34. - name: "metrics"
  35. containerPort: 9400
  36. securityContext:
  37. runAsNonRoot: false
  38. runAsUser: 0
  39. volumeMounts:
  40. - name: "pod-gpu-resources"
  41. readOnly: true
  42. mountPath: "/var/lib/kubelet/pod-resources"
  43. volumes:
  44. - name: "pod-gpu-resources"
  45. hostPath:
  46. path: "/var/lib/kubelet/pod-resources"
  47. ---
  48. kind: Service
  49. apiVersion: v1
  50. metadata:
  51. name: "dcgm-exporter"
  52. namespace: monitoring
  53. labels:
  54. app.kubernetes.io/name: "dcgm-exporter"
  55. app.kubernetes.io/version: "2.4.0"
  56. spec:
  57. selector:
  58. app.kubernetes.io/name: "dcgm-exporter"
  59. app.kubernetes.io/version: "2.4.0"
  60. ports:
  61. - name: "metrics"
  62. port: 9400

提交配置k8s

  1. kubectl apply -f ./dcgm-exporter.yaml

支持指标

Nvidia GPU 指标量收集, 提供GPU指标和对应GPU指标属于那个容器、POD。指标量能够和POD、Container进行关联例如:

  1. DCGM_FI_DEV_DEC_UTIL{gpu="2",UUID="GPU-09239326-4101-8dd9-272b-32bf5615f996",device="nvidia2",modelName="NVIDIA GeForce RTX 3090",Hostname="dcgm-exporter-b6sgj",container="dlapi",namespace="cloud-gpu",pod="dlapi-5caeac72582e35c560667d21-6141a02e0d828f8e81bee064-595z5d2"} 0

GPU 使用率

DCGM_FI_DEV_GPU_UTIL

GPU 显存

  • GPU 已用内存: DCGM_FI_DEV_FB_USED
  • GPU 空闲内存:DCGM_FI_DEV_FB_FREE
  • 内存使用率: DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE)

GPU 温度

DCGM_FI_DEV_GPU_TEMP

GPU指标量保存Prometheus

目前我们使用prometheus operator, 只要配置service-monitor就可以对应prometheus收集指标量了。下面yaml如下:

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: ServiceMonitor
  3. metadata:
  4. generation: 1
  5. labels:
  6. app.kubernetes.io/name: "dcgm-exporter"
  7. app.kubernetes.io/version: "2.4.0"
  8. name: dcgm-exporter
  9. namespace: monitoring
  10. spec:
  11. endpoints:
  12. - interval: 60s # 拉取频率
  13. port: http-metrics
  14. jobLabel: k8s-app # 对应 prometheus-operator 创建收集实例 serviceMonitorSelector.matchExpressions
  15. namespaceSelector:
  16. matchNames:
  17. - monitoring
  18. selector:
  19. matchLabels:
  20. app.kubernetes.io/name: "dcgm-exporter"
  21. app.kubernetes.io/version: "2.4.0"

基于GPU使用率弹性伸缩

Keda 支持获取对应 promethus 拉取指标量进行弹性伸缩, 支持promethus 查询语句。模型deployment弹性伸缩,可以根据模型平均GPU使用率进行伸缩。

获取制定模型实例平均GPU使用率

例如模型 deployment 名称 58ecbfb07c7ae7056a96a3b1-image-common-production, 获取这个deployment 所有实例GPU平均使用率:

  1. avg(DCGM_FI_DEV_GPU_UTIL{pod_name=~"58ecbfb07c7ae7056a96a3b1-image-common-production-.*"})

配置GPU弹性伸缩样例

下面是通过GPU使用率进行

  1. apiVersion: keda.sh/v1alpha1
  2. kind: ScaledObject
  3. metadata:
  4. name: 58ecbfb07c7ae7056a96a3b1-image-common-production
  5. namespace: {{ deployment-namespace }}
  6. spec:
  7. maxReplicaCount: 12 # 最大扩展实例数目
  8. scaleTargetRef:
  9. name: 58ecbfb07c7ae7056a96a3b1-image-common-production
  10. kind: Deployment
  11. apiVersion: apiVersion
  12. triggers:
  13. - type: prometheus
  14. metadata:
  15. serverAddress: http://<prometheus-host>:9090
  16. metricName: 58ecbfb07c7ae7056a96a3b1-image-common-production-gpu-avg # 每个伸缩指标量都必须唯一
  17. threshold: '70' # GPU 使用率 > 70 增加实例
  18. query: avg(DCGM_FI_DEV_GPU_UTIL{pod_name=~"58ecbfb07c7ae7056a96a3b1-image-common-production-.*"})

参考