当前位置:   article > 正文

Kubernetes管理GPU_gpu的在kubernetes监控

gpu的在kubernetes监控

历史原因,容器技术设计之初,人工智能还未得到真正的应用,所以容器设计的侧重点主要在于隔离性和可移植性,随着OpenAI的横空出世,机器学习迎来了井喷发展,GPU因其出色的计算能力更是得到了更大规模的应用。而作为目前最主流的云原生平台,如何管理GPU资源,对Kubernetes显得越发重要。

原理实现

前面讲了,容器技术的主要特点之一是隔离性,所以原生是不支持GPU的,虽然Docker在1.19版本后原生集成了nvidia-docker,但这只是解决了容器使用GPU的问题,而大规模的在Kubernetes上应用,还需要解决资源调度和管理的问题。Kubernetes提供了一个设备插件框架用来解决这个问题,它可以将系统硬件资源发布到kubelet上,大致原理是:

kubelet提供了一个Registration的gRPC服务,设备插件通过gRPC服务向kubelet进行注册,注册成功后,设备插件就向kubelet发送它所管理的设备列表,然后kubelet负责将GPU资源发布到API服务器,做为kubelet节点状态更新的一部分。其中注册期间设备插件需要发送下面几样内容:

  • 设备插件的Unix套接字
  • 设备插件的API版本
  • ResourceName(资源名称,如NVIDIA的名称为nvidia.com/gpu)

设备插件采用守护进程的方式部署,具体工作流程分四个阶段:

  1. 完成设备初始化,确保设备处于就绪状态
  2. 设备插件会尝试在节点的/var/lib/kubelet/device-plugins/目录下创建一个UNIX套接字,启动一个gRPC服务。任何设备都必须支持以下RPC:
    1. service DevicePlugin {
    2. // GetDevicePluginOptions 返回与设备管理器沟通的选项。
    3. rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
    4. // ListAndWatch 返回 Device 列表构成的数据流。
    5. // 当 Device 状态发生变化或者 Device 消失时,ListAndWatch
    6. // 会返回新的列表。
    7. rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
    8. // Allocate 在容器创建期间调用,这样设备插件可以运行一些特定于设备的操作,
    9. // 并告诉 kubelet 如何令 Device 可在容器中访问的所需执行的具体步骤
    10. rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
    11. // GetPreferredAllocation 从一组可用的设备中返回一些优选的设备用来分配,
    12. // 所返回的优选分配结果不一定会是设备管理器的最终分配方案。
    13. // 此接口的设计仅是为了让设备管理器能够在可能的情况下做出更有意义的决定。
    14. rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
    15. // PreStartContainer 在设备插件注册阶段根据需要被调用,调用发生在容器启动之前。
    16. // 在将设备提供给容器使用之前,设备插件可以运行一些诸如重置设备之类的特定于
    17. // 具体设备的操作,
    18. rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
    19. }
  3. 通过节点路径/var/lib/kubelet/device-plugins/kubelet.sock下的UNIX套接字相kubelet注册自身
  4. 成功注册自身后,设备插件将以提供服务的模式运行,在此期间,它将持续监控设备运行状况, 并在设备状态发生任何变化时向 kubelet 报告

部署参考

我们以NVIDIA为示例,首先安装nvidia-container-toolkit,具体安装步骤可以参考官方链接Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.14.5 documentation

然后部署naidia-device-plugin,Yaml文件参考如下:

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: nvidia-device-plugin-daemonset
  5. namespace: kube-system
  6. spec:
  7. selector:
  8. matchLabels:
  9. name: nvidia-device-plugin-ds
  10. updateStrategy:
  11. type: RollingUpdate
  12. template:
  13. metadata:
  14. labels:
  15. name: nvidia-device-plugin-ds
  16. spec:
  17. tolerations:
  18. - key: nvidia.com/gpu
  19. operator: Exists
  20. effect: NoSchedule
  21. # Mark this pod as a critical add-on; when enabled, the critical add-on
  22. # scheduler reserves resources for critical add-on pods so that they can
  23. # be rescheduled after a failure.
  24. # See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/
  25. priorityClassName: "system-node-critical"
  26. containers:
  27. - image: nvcr.io/nvidia/k8s-device-plugin:v0.14.5
  28. name: nvidia-device-plugin-ctr
  29. env:
  30. - name: FAIL_ON_INIT_ERROR
  31. value: "false"
  32. securityContext:
  33. allowPrivilegeEscalation: false
  34. capabilities:
  35. drop: ["ALL"]
  36. volumeMounts:
  37. - name: device-plugin
  38. mountPath: /var/lib/kubelet/device-plugins
  39. volumes:
  40. - name: device-plugin
  41. hostPath:
  42. path: /var/lib/kubelet/device-plugins

 调度使用

部署完成后,既可以使用nvidia.com/gpu进行资源调度,示例如下:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: gpu-pod
  5. spec:
  6. restartPolicy: Never
  7. containers:
  8. - name: cuda-container
  9. image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
  10. resources:
  11. limits:
  12. nvidia.com/gpu: 1 # 请求1个GPU
  13. tolerations:
  14. - key: nvidia.com/gpu
  15. operator: Exists
  16. effect: NoSchedule

使用事项

  1. 设备插件功能的稳定版本始于1.26,所以建议使用不低于1.26版本的Kubernetes stable版本
  2. 在创建Pod定义资源请求的时候,GPU不同于CPU,limits和requests的值必须相等,可以仅指定limits(仅指定limits时,Kubernetes会默认requests为limits的值),但不能仅指定request
  3. 可以利用节点标签及节点亲和性来管理不同类型的GPU节点,标签有两种,一种是自定义的,另一种是通过部署NFD实现的自动标签,具体可以依据Kubernetes集群的规模和节点类型复杂度酌情选择。如规模较大或者节点类型较多,NFD会是更好的选择。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/657782
推荐阅读
相关标签
  

闽ICP备14008679号