如何在kubernetes环境中共享GPU

news/2024/10/13 12:02:26

随着人工智能和大模型的快速发展,云上GPU资源共享变得必要,因为它可以降低硬件成本,提升资源利用效率,并满足模型训练和推理对大规模并行计算的需求。

在kubernetes内置的资源调度功能中,GPU调度只能根据“核数”进行调度,但是深度学习等算法程序执行过程中,资源占用比较高的是显存,这样就形成了很多的资源浪费。

目前的GPU资源共享方案有两种。一种是将一个真正的GPU分解为多个虚拟GPU,即vGPU,这样就可以基于vGPU的数量进行调度;另一种是根据GPU的显存进行调度。

本文将讲述如何安装kubernetes组件实现根据GPU显存调度资源。

系统信息

  • 系统:centos stream8

  • 内核:4.18.0-490.el8.x86_64

  • 驱动:NVIDIA-Linux-x86_64-470.182.03

  • docker:20.10.24

  • kubernetes版本:1.24.0

1. 驱动安装

请登录nvida官网自行安装:https://www.nvidia.com/Download/index.aspx?lang=en-us

2. docker安装

请自行安装docker或其他容器运行时,如果使用其他容器运行时,第三步配置请参考NVIDA官网 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installation-guide

注意:官方支持docker、containerd、podman,但本文档只验证过docker的使用,如果使用其他容器运行时,请注意差异性。

3. NVIDIA Container Toolkit 安装

  1. 设置仓库与GPG Key
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \&& curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
  1. 开始安装
sudo dnf clean expire-cache --refresh
sudo dnf install -y nvidia-container-toolkit
  1. 修改docker配置文件添加容器运行时实现
sudo nvidia-ctk runtime configure --runtime=docker
  1. 修改/etc/docker/daemon.json,设置nvidia为默认容器运行时(必需)
{"default-runtime": "nvidia","runtimes": {"nvidia": {"path": "/usr/bin/nvidia-container-runtime","runtimeArgs": []}}
}
  1. 重启docker并开始验证是否生效
sudo systemctl restart docker
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:11.6.2-base-ubuntu20.04 nvidia-smi

如果返回如下数据,说明配置成功

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.51.06    Driver Version: 450.51.06    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
| N/A   34C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
​
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

4. 安装K8S GPU调度器

  1. 首先执行以下yaml,部署调度器
# rbac.yaml
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: gpushare-schd-extender
rules:- apiGroups:- ""resources:- nodesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- ""resources:- podsverbs:- update- patch- get- list- watch- apiGroups:- ""resources:- bindings- pods/bindingverbs:- create- apiGroups:- ""resources:- configmapsverbs:- get- list- watch
---
apiVersion: v1
kind: ServiceAccount
metadata:name: gpushare-schd-extendernamespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: gpushare-schd-extendernamespace: kube-system
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: gpushare-schd-extender
subjects:- kind: ServiceAccountname: gpushare-schd-extendernamespace: kube-system
​
# deployment yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:name: gpushare-schd-extendernamespace: kube-system
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: gpusharecomponent: gpushare-schd-extendertemplate:metadata:labels:app: gpusharecomponent: gpushare-schd-extenderannotations:scheduler.alpha.kubernetes.io/critical-pod: ''spec:hostNetwork: truetolerations:- effect: NoScheduleoperator: Existskey: node-role.kubernetes.io/master- effect: NoSchedulekey: node-role.kubernetes.io/control-planeoperator: Exists- effect: NoScheduleoperator: Existskey: node.cloudprovider.kubernetes.io/uninitializednodeSelector:node-role.kubernetes.io/control-plane: ""serviceAccount: gpushare-schd-extendercontainers:- name: gpushare-schd-extenderimage: registry.cn-hangzhou.aliyuncs.com/acs/k8s-gpushare-schd-extender:1.11-d170d8aenv:- name: LOG_LEVELvalue: debug- name: PORTvalue: "12345"
​
# service.yaml
---
apiVersion: v1
kind: Service
metadata:name: gpushare-schd-extendernamespace: kube-systemlabels:app: gpusharecomponent: gpushare-schd-extender
spec:type: NodePortports:- port: 12345name: httptargetPort: 12345nodePort: 32766selector:# select app=ingress-nginx podsapp: gpusharecomponent: gpushare-schd-extender
  1. 在/etc/kubernetes目录下添加调度策略配置文件
#scheduler-policy-config.yaml
---
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
clientConnection:kubeconfig: /etc/kubernetes/scheduler.conf
extenders:# 不知道为什么不支持svc的方式调用,必须用nodeport- urlPrefix: "http://gpushare-schd-extender.kube-system:12345/gpushare-scheduler"filterVerb: filterbindVerb: bindenableHTTPS: falsenodeCacheCapable: truemanagedResources:- name: aliyun.com/gpu-memignoredByScheduler: falseignorable: false

上面的 http://gpushare-schd-extender.kube-system:12345 注意要替换为你本地部署的{nodeIP}:{gpushare-schd-extender的nodeport端口},否则会访问不到

查询命令如下:

kubectl get service gpushare-schd-extender -n kube-system -o jsonpath='{.spec.ports[?(@.name=="http")].nodePort}'
  1. 修改kubernetes调度配置 /etc/kubernetes/manifests/kube-scheduler.yaml
1. 在commond中添加- --config=/etc/kubernetes/scheduler-policy-config.yaml
​
2. 添加pod挂载目录
在volumeMounts:中添加
- mountPath: /etc/kubernetes/scheduler-policy-config.yamlname: scheduler-policy-configreadOnly: true
在volumes:中添加
- hostPath:path: /etc/kubernetes/scheduler-policy-config.yamltype: FileOrCreatename: scheduler-policy-config

注意:这里千万不要改错,否则可能会出现莫名其妙的错误
示例如下:

  1. 配置rbac及安装device插件
kubectl create -f https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-rbac.yaml
kubectl create -f https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-ds.yaml

5. 在GPU节点上添加标签

kubectl label node <target_node> gpushare=true

6. 安装kubectl Gpu 插件

cd /usr/bin/
wget https://github.com/AliyunContainerService/gpushare-device-plugin/releases/download/v0.3.0/kubectl-inspect-gpushare
chmod u+x /usr/bin/kubectl-inspect-gpushare

7. 验证

  1. 使用kubectl查询GPU资源使用情况
# kubectl inspect gpushare
NAME                                IPADDRESS     GPU0(Allocated/Total)  GPU Memory(GiB)
cn-shanghai.i-uf61h64dz1tmlob9hmtb  192.168.0.71  6/15                   6/15
cn-shanghai.i-uf61h64dz1tmlob9hmtc  192.168.0.70  3/15                   3/15
------------------------------------------------------------------------------
Allocated/Total GPU Memory In Cluster:
9/30 (30%)
  1. 创建一个有GPU需求的资源,查看其资源调度情况
apiVersion: apps/v1
kind: Deployment
metadata:name: binpack-1labels:app: binpack-1
spec:replicas: 1selector: # define how the deployment finds the pods it managesmatchLabels:app: binpack-1template: # define the pods specificationsmetadata:labels:app: binpack-1spec:tolerations:- effect: NoSchedulekey: cloudClusterNooperator: Exists        containers:- name: binpack-1image: cheyang/gpu-player:v2resources:limits:# 单位GiBaliyun.com/gpu-mem: 3

8. 问题排查

如果在安装过程中发现资源未安装成功,可以通过pod查看日志

kubectl get po -n kube-system -o=wide | grep gpushare-device 
kubecl logs -n kube-system <pod_name>

参考地址:
NVIDA官网container-toolkit安装文档: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker
阿里云GPU插件安装:https://github.com/AliyunContainerService/gpushare-scheduler-extender/blob/master/docs/install.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/71032.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

WGCLOUD使用笔记 - 监测主机的Crontab定时任务信息

Crontab定时任务监测,是WGCLOUD v3.5.5 新增的一个功能模块可以实时监测Linux的Crontab设置信息,如下图

高级程序语言设计课程第三次个人作业

班级的链接:https://edu.cnblogs.com/campus/fzu/2024C/ 作业要求的链接:https://edu.cnblogs.com/campus/fzu/2024C/homework/13284 学号:102400228 姓名:吴昊 第四章作业: 第二题:本题在b.d要求读题时有部分困难,最后通过网上查询解决自己的困难 第三题:本题没什么大…

golong下载

https://www.cnblogs.com/se6c/p/17890974.html#gallery-2 目录中文网官网编译器下载额外步骤:加速访问配置 GOPROXY 环境变量,以下三选一给你们看下我的这一步步骤(我选的阿里) 中文网首页 - Go语言中文网 - Golang中文社区官网The Go Programming Language编译器下载1.我…

通过LambdaQueryWrapper配置实现查询指定的字段值

如果是自己写sql语句,可以很自由的实现查询哪些字段值,但是在使用 MybatisPlus 提供的CRUD方法的时候我们该如何实现这一效果呢? 可以通过 LambdaQueryWrapper 和 QueryWrapper 的 select 方法来做到这一点public IPage<Customer> page(int current, int size) {log.i…

Scratch列表的知识与应用

列表及应用1 列表及应用2 练习题1

2024-2025-3-计算机基础与程序设计

学期(如2024-2025-3) 学号(20241404) 《计算机基础与程序设计》第3周学习总结 作业信息这个作业属于哪个课程 <计算机基础程序与设计>这个作业要求在哪里 https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP/homework/13265这个作业的目标 <帮助我们更深刻理…

硬件设计很简单?合宙低功耗4G模组Air780E—开机启动及外围电路设计

​ Air780E是合宙低功耗4G-Cat.1模组经典型号之一,上期我们解答了大家关心的系列问题,并讲解了选型的注意要点。 有朋友问:能不能讲些硬件设计相关的内容? 模组的上电开机,是硬件设计调试的第一步。本期特别分享——Air780E开机启动及外围电路设计。Air780E开机启动及外围…