赞
踩
历史原因,容器技术设计之初,人工智能还未得到真正的应用,所以容器设计的侧重点主要在于隔离性和可移植性,随着OpenAI的横空出世,机器学习迎来了井喷发展,GPU因其出色的计算能力更是得到了更大规模的应用。而作为目前最主流的云原生平台,如何管理GPU资源,对Kubernetes显得越发重要。
前面讲了,容器技术的主要特点之一是隔离性,所以原生是不支持GPU的,虽然Docker在1.19版本后原生集成了nvidia-docker,但这只是解决了容器使用GPU的问题,而大规模的在Kubernetes上应用,还需要解决资源调度和管理的问题。Kubernetes提供了一个设备插件框架用来解决这个问题,它可以将系统硬件资源发布到kubelet上,大致原理是:
kubelet提供了一个Registration的gRPC服务,设备插件通过gRPC服务向kubelet进行注册,注册成功后,设备插件就向kubelet发送它所管理的设备列表,然后kubelet负责将GPU资源发布到API服务器,做为kubelet节点状态更新的一部分。其中注册期间设备插件需要发送下面几样内容:
设备插件采用守护进程的方式部署,具体工作流程分四个阶段:
-
- service DevicePlugin {
- // GetDevicePluginOptions 返回与设备管理器沟通的选项。
- rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
-
- // ListAndWatch 返回 Device 列表构成的数据流。
- // 当 Device 状态发生变化或者 Device 消失时,ListAndWatch
- // 会返回新的列表。
- rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
-
- // Allocate 在容器创建期间调用,这样设备插件可以运行一些特定于设备的操作,
- // 并告诉 kubelet 如何令 Device 可在容器中访问的所需执行的具体步骤
- rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
-
- // GetPreferredAllocation 从一组可用的设备中返回一些优选的设备用来分配,
- // 所返回的优选分配结果不一定会是设备管理器的最终分配方案。
- // 此接口的设计仅是为了让设备管理器能够在可能的情况下做出更有意义的决定。
- rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
-
- // PreStartContainer 在设备插件注册阶段根据需要被调用,调用发生在容器启动之前。
- // 在将设备提供给容器使用之前,设备插件可以运行一些诸如重置设备之类的特定于
- // 具体设备的操作,
- rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
- }
-
-
/var/lib/kubelet/device-plugins/kubelet.sock下的UNIX套接字相kubelet注册自身
我们以NVIDIA为示例,首先安装nvidia-container-toolkit,具体安装步骤可以参考官方链接Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.14.5 documentation
然后部署naidia-device-plugin,Yaml文件参考如下:
- apiVersion: apps/v1
- kind: DaemonSet
- metadata:
- name: nvidia-device-plugin-daemonset
- namespace: kube-system
- spec:
- selector:
- matchLabels:
- name: nvidia-device-plugin-ds
- updateStrategy:
- type: RollingUpdate
- template:
- metadata:
- labels:
- name: nvidia-device-plugin-ds
- spec:
- tolerations:
- - key: nvidia.com/gpu
- operator: Exists
- effect: NoSchedule
- # Mark this pod as a critical add-on; when enabled, the critical add-on
- # scheduler reserves resources for critical add-on pods so that they can
- # be rescheduled after a failure.
- # See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/
- priorityClassName: "system-node-critical"
- containers:
- - image: nvcr.io/nvidia/k8s-device-plugin:v0.14.5
- name: nvidia-device-plugin-ctr
- env:
- - name: FAIL_ON_INIT_ERROR
- value: "false"
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop: ["ALL"]
- volumeMounts:
- - name: device-plugin
- mountPath: /var/lib/kubelet/device-plugins
- volumes:
- - name: device-plugin
- hostPath:
- path: /var/lib/kubelet/device-plugins
部署完成后,既可以使用nvidia.com/gpu进行资源调度,示例如下:
- apiVersion: v1
- kind: Pod
- metadata:
- name: gpu-pod
- spec:
- restartPolicy: Never
- containers:
- - name: cuda-container
- image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
- resources:
- limits:
- nvidia.com/gpu: 1 # 请求1个GPU
- tolerations:
- - key: nvidia.com/gpu
- operator: Exists
- effect: NoSchedule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。