前言
AI
落地时,在某些场景下 AI
模型在训练或者是推理时,其算力要求不需要占用整卡的 GPU
,比如只需要0.5卡 GPU
即可满足需求。
在这种情况下,可以使用 GPU
虚拟化技术来解决这个问题,将整卡的 GPU
虚拟化为两个0.5卡的 GPU
,这样就可以在一张卡上同时跑两个 AI
训练或者 AI
推理应用服务,极大压榨算力资源,降低成本。
vGPU
是 NVIDIA
提供的一种 GPU
虚拟化的一种方案,同时也可以实现对多用户的强 GPU
隔离方案
基本痛点:
- 容器使用的单卡
GPU
利用率不够高,特别是推理任务; - 为了提高
GPU
的利用率、避免算力浪费,需要在单个GPU
上运行多个容器 - 而
vGPU
的使用需要额外从NVIDIA
公司购买license
。年度订阅和永久许可证
其他vGPU插件
https://github.com/4paradigm/k8s-vgpu-scheduler
4paradigm
提供了 k8s-device-plugin
,该插件基于NVIDIA官方插件( NVIDIA/k8s-device-plugin
),在保留官方功能的基础上,实现了对物理 GPU
进行切分,并对显存和计算单元进行限制,从而模拟出多张小的 vGPU卡`。
在 k8s
集群中,基于这些切分后的 vGPU
进行调度,使不同的容器可以安全的共享同一张物理 GPU
,提高 GPU
的利用率。
此外,插件还可以对显存做虚拟化处理(使用到的显存可以超过物理上的显存),运行一些超大显存需求的任务,或提高共享的任务数。
部署
配置docker
nvidia-smi
命令,查看当前显卡信息
如果你使用了 docker
,需要讲将 nvidia runtime
设置为 docker runtime
预设值,此文件通常在 /etc/docker/daemon.json
路径:
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
docker
重新加载配置
systemctl daemon-reload && systemctl restart docker
配置containerd
你需要在节点上将 nvidia runtime
做为你的 containerd runtime
预设值。
我们将编辑 containerd daemon
的配置文件,此文件通常在 /etc/containerd/config.toml
路径
version = 2
[plugins]
[plugins."io.containerd.grpc.v1.cri"]
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "nvidia"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
privileged_without_host_devices = false
runtime_engine = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]
BinaryName = "/usr/bin/nvidia-container-runtime"
containerd
重新加载配置
systemctl daemon-reload && systemctl restart containerd
查看当前gpu分配情况
可以通过 kubectl describe node node1
命令,查看你指定节点的 gpu
个数情况:
Allocatable:
cpu: 32
ephemeral-storage: 94059137278
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 65738804Ki
nvidia.com/gpu: 2
pods: 110
关闭NVIDIA官方插件
把 nvidia-device-plugin ds
描述文件移除即可,为安全可以移动到其它目录,如下移动到家目录做备份保存。
mv /etc/kubernetes/manifests/nvidia-device-plugin.yml .
启用新的gpu设备插件
启动 4paradigm
新的 k8s-device-plugin
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:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
labels:
name: nvidia-device-plugin-ds
spec:
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
priorityClassName: "system-node-critical"
containers:
- image: 4pdosc/k8s-device-plugin:latest
imagePullPolicy: Always
name: nvidia-device-plugin-ctr
args: ["--fail-on-init-error=false", "--device-split-count=6", "--device-memory-scaling=2", "--device-cores-scaling=1"]
env:
- name: PCIBUSFILE
value: "/usr/local/vgpu/pciinfo.vgpu"
- name: NVIDIA_MIG_MONITOR_DEVICES
value: all
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["SYS_ADMIN"]
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
- name: vgpu-dir
mountPath: /usr/local/vgpu
- mountPath: /tmp
name: hosttmp
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
- name: vgpu-dir
hostPath:
path: /usr/local/vgpu
- hostPath:
path: /tmp
name: hosttmp
nodeSelector:
nvidia-vgpu: "on"
将以上代码保存为 vgpu-nvdp.yaml
文件,然后安装
kubectl apply -f vgpu-nvdp.yaml
打上gpu标签
在需要进行虚拟化的节点打上标签 nvidia-vgpu:"on"
,否则该节点不会被调度到,或者你打其他标签也行,取决于你设置的 nodeSelector
kubectl label node {nodeid} nvdia-vgpu=on
等插件部署完成后,再次执行 kubectl describe node node1
命令,查看节点的 gpu
个数情况
运行GPU任务
NVIDIA vGPUs
现在能透过资源类型 nvidia.com/gpu
被容器请求:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: ubuntu-container
image: ubuntu:18.04
command: ["bash", "-c", "sleep 86400"]
resources:
limits:
nvidia.com/gpu: 2 # 请求2个vGPUs
nvidia.com/gpumem: 3000 # 每个vGPU申请3000m显存 (可选,整数类型)
nvidia.com/gpucores: 30 # 每个vGPU的算力为30%实际显卡的算力 (可选,整数类型)
如果你的任务无法运行在任何一个节点上(例如任务的 nvidia.com/gpu
大于集群中任意一个 GPU
节点的实际 GPU
数量),那么任务会卡在 pending
状态
现在你可以在容器执行 nvidia-smi
命令,然后比较 vGPU
和实际 GPU
显存大小的不同。
监控vGPU使用情况
调度器部署成功后,监控默认自动开启,你可以通过
http://{nodeip}:{monitorPort}/metrics
来获取监控数据,其中 monitorPort
可以在 Values
中进行配置,默认为 31992
grafana dashboard
示例:https://github.com/4paradigm/k8s-vgpu-scheduler/blob/master/docs/dashboard_cn.md
标签:name,kubernetes,containerd,vGPU,vgpu,nvidia,device,GPU,安装 From: https://www.cnblogs.com/niuben/p/18160759注意 节点上的
vGPU
状态只有在其使用vGPU
后才会被统计W