快速体验NVIDIA在k8s中下一代设备管理插件

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 背景Kubernetes 1.26开始引入DRA( Dynamic Resource Allocation,动态资源分配),用于解决Kubernetes现有Device Plugin机制的不足。相比于现有的Device Plugin机制,DRA更加开放和自主,能够满足一些复杂的使用场景。NVIDIA、Intel这些设备厂商也基于DRA开放自己下一代Device Plugin,以期满足更复杂的业务场

背景

Kubernetes 1.26开始引入DRA( Dynamic Resource Allocation,动态资源分配),用于解决Kubernetes现有Device Plugin机制的不足。相比于现有的Device Plugin机制,DRA更加开放和自主,能够满足一些复杂的使用场景。

NVIDIA、Intel这些设备厂商也基于DRA开放自己下一代Device Plugin,以期满足更复杂的业务场景。

NVIDIA Resource Driver介绍

NVIDIA Resource Driver是基于K8s DRA机制实现,项目地址为:https://gitlab.com/nvidia/cloud-native/k8s-dra-driver。目前支持如下的一些功能:

  • 支持独占GPU调度:一个Pod中容器独占使用一张或多张GPU卡。
  • 支持共享GPU调度:多个Pod运行在一张GPU卡上。
  • 支持MPS:允许Pod使用GPU MPS能力。
  • 支持Time-Slicing:允许Pod使用GPU Time-Slicing能力。

目前该项目还不是一个生产可用的状态,所以不建议将该组件部署在生产环境中,仅作为学习和测试环境使用。

前提条件

在体验NVIDIA Resource Driver之前,有如下的一些条件需要满足:

  • K8S版本>= 1.27.0,目前NVIDIA Resource Driver使用DRA  API版本为v1alpha2,这个API版本当前仅在1.27中才支持。
  • Container >= 1.7.0,DRA机制需要Containerd CDI功能参与,目前CDI能力仅在Containerd 1.7.0及其以上才支持。
  • 实验环境:一台带GPU设备的物理机(或者虚拟机、云上机器都行),已安装操作系统,本次实验使用的操作系统为CentOS 7.9。

步骤

为了快速体验NVIDIA Resource Driver,本篇文章将借助minikube快速搭建一个v1.27.3的K8s集群,然后在集群中部署NVIDIA Resource Driver。

安装NVIDIA驱动

安装驱动依赖包

在节点上使用如下命令安装驱动依赖包。

yum install -y gcc dracut kernel-devel-$(uname -r)

禁用nouveau。

mkdir -pv /etc/modprobe.d/

echo 'blacklist nouveau' >/etc/modprobe.d/blacklist-nouveau.conf

echo 'options nouveau modeset=0' >>/etc/modprobe.d/blacklist-nouveau.conf		

安装NVIDIA驱动

NVIDIA官方界面下面驱动,这里以515.105.01为例,得到的驱动文件如下。

NVIDIA-Linux-x86_64-515.105.01.run

安装驱动文件。

sh NVIDIA-Linux-x86_64-515.105.01.run -a -s -q 

安装完成后执行nvidia-smi。

nvidia-smi

输出如下。

Mon Jul 10 12:06:09 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 515.105.01   Driver Version: 515.105.01   CUDA Version: 11.7     |
|-------------------------------+----------------------+----------------------+
| 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 V100-SXM2...  On   | 00000000:00:07.0 Off |                    0 |
| N/A   34C    P0    40W / 300W |      0MiB / 32768MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-SXM2...  On   | 00000000:00:08.0 Off |                    0 |
| N/A   35C    P0    40W / 300W |      0MiB / 32768MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   2  Tesla V100-SXM2...  On   | 00000000:00:09.0 Off |                    0 |
| N/A   35C    P0    42W / 300W |      0MiB / 32768MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   3  Tesla V100-SXM2...  On   | 00000000:00:0A.0 Off |                    0 |
| N/A   33C    P0    39W / 300W |      0MiB / 32768MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

可以看到,本次示例的节点有4张GPU卡。

目前NVIDIA Resource Driver要求NVIDIA驱动的安装路径为/run/nvidia/driver(当前使用CDI机制生成NVIDIA CDI设备的限制,后续NVIDIA将解除这个限制),所以将节点的根目录挂载到/run/nvidia/driver。

mkdir -p /run/nvidia

ln -sv   /  /run/nvidia/driver

准备Container Runtime环境

在利用minikube构建集群之前,需要配置Container Runtime环境。

安装runc

登录实验环境,下载runc二进制文件。

wget https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64

将runc二进制文件存放到/usr/bin。

cp runc.amd64 /usr/bin/runc

添加执行权限。

chmod +x /usr/bin/runc

安装cni

登录实验环境,下载cni组件安装包。

wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz

解压并安装cni。

mkdir -pv /opt/cni/bin

tar Cxzvf /opt/cni/bin  cni-plugins-linux-amd64-v1.3.0.tgz

安装crictl

登录实验环境,下载crictl。

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.0/crictl-v1.27.0-linux-amd64.tar.gz

解压并安装到/usr/bin。

tar -xf crictl-v1.27.0-linux-amd64.tar.gz

cp crictl /usr/bin

添加配置文件。

echo 'runtime-endpoint: unix:///var/run/containerd/containerd.sock' > /etc/crictl.yaml

安装docker-cli

安装docker-cli的这一步主要是让minikube能够正常创建集群,没有安装docker-cli,minikube创建集群会报错。

安装yum工具。

yum install -y yum-utils

配置docker yum源。

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安装docker client。

 yum install  -y docker-ce-cli

安装containerd

下载containerd安装包。

wget https://github.com/containerd/containerd/releases/download/v1.7.2/containerd-1.7.2-linux-amd64.tar.gz

解压containerd安装包,并安装到/usr/bin。

tar -xf containerd-1.7.2-linux-amd64.tar.gz

cp bin/containerd /usr/bin

创建配置文件。

containerd config default | sudo tee /etc/containerd/config.toml

更改配置文件某些配置。

sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

在配置文件中添加CDI配置。

  [plugins."io.containerd.grpc.v1.cri"]
    enable_cdi = true
    cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]

创建cdi相关目录。

mkdir -pv /etc/cdi /var/run/cdi

下载systemd风格启动脚本。

curl -L https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /etc/systemd/system/containerd.service

启动和开机自启containerd。

systemctl daemon-reload

 systemctl enable --now containerd

查看containerd状态。

systemctl status containerd

类似有如下的输出。

● containerd.service - containerd container runtime
   Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: disabled)
   Active: active (running) since 三 2023-07-05 20:00:29 CST; 4 days ago
     Docs: https://containerd.io
 Main PID: 1763365 (containerd)
    Tasks: 154
   Memory: 144.8M
   CGroup: /system.slice/containerd.service
           ├─1763365 /usr/bin/containerd

安装minikube

下载minikube。

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

安装到/usr/local/bin。

cp minikube-linux-amd64 /usr/local/bin/minikube

添加执行权限。

chmod +x /usr/local/bin/minikube

安装kubectl

下载kubectl。

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

安装到/usr/local/bin。

cp kubectl /usr/local/bin/kubectl

添加执行权限。

chmod +x /usr/local/bin/kubectl

安装helm

安装NVIDIA Resource Driver需要使用helm。

首先下载helm。

curl -LO https://get.helm.sh/helm-v3.12.1-linux-amd64.tar.gz

解压。

tar -xf helm-v3.12.1-linux-amd64.tar.gz

安装到/usr/local/bin。

cp linux-amd64/helm /usr/local/bin

创建k8s集群

使用如下命令创建k8s集群。

minikube start \
	--force \
	--driver=none \
	--force-systemd=true \
	--container-runtime=containerd \
	--cni=flannel \
	--kubernetes-version=v1.27.3 \
	--extra-config=apiserver.runtime-config=resource.k8s.io/v1alpha2 \
	--feature-gates=DynamicResourceAllocation=true

集群创建成功后,查看各个组件状态是否都处于running。

$ kubectl get po -n kube-system

NAME                                              READY   STATUS    RESTARTS   AGE
coredns-5d78c9869d-svbhf                          1/1     Running   0          4d14h
etcd-izj6ce3r1zhvbsrk3ww4cpz                      1/1     Running   3          4d14h
kube-apiserver-izj6ce3r1zhvbsrk3ww4cpz            1/1     Running   3          4d14h
kube-controller-manager-izj6ce3r1zhvbsrk3ww4cpz   1/1     Running   3          4d14h
kube-proxy-rgb4c                                  1/1     Running   0          4d14h
kube-scheduler-izj6ce3r1zhvbsrk3ww4cpz            1/1     Running   0          4d14h
storage-provisioner                               1/1     Running   0          4d14h

查看集群节点。

$ kubectl get nodes

NAME                      STATUS   ROLES           AGE     VERSION
izj6ce3r1zhvbsrk3ww4cpz   Ready    control-plane   4d15h   v1.27.3

安装NVIDIA Resource Driver

下载NVIDIA Resource Driver项目。

git clone https://gitlab.com/nvidia/cloud-native/k8s-dra-driver.git

修改deployments/helm/k8s-dra-driver/templates/kubeletplugin.yaml中环境变量LD_LIBRARY_PATH的值(/run/nvidia/driver/usr/lib/x86_64-linux-gnu这个路径存在问题),修改前的效果如下。

        - name: LD_LIBRARY_PATH
          value: /usr/lib64/:/run/nvidia/driver/usr/lib/x86_64-linux-gnu

修改后的效果如下。

        - name: LD_LIBRARY_PATH
          value: /usr/lib64/:/run/nvidia/driver/usr/lib:/run/nvidia/driver/usr/lib64

安装nvidia resource driver。

$ helm install  --create-namespace --namespace nvidia-dra-driver nvidia-dra  deployments/helm/k8s-dra-driver 

使用minikube搭建的集群只有一个节点,那就是当前操作的节点,给这个节点打上标签。

$ kubectl label nodes <NODE_NAME>  nvidia.com/dra.kubelet-plugin=true
$ kubectl label nodes <NODE_NAME>  nvidia.com/dra.controller=true

等待dra组件处于running。

$ kubectl get po -n nvidia-dra-driver
NAME                                                READY   STATUS    RESTARTS   AGE
nvidia-k8s-dra-driver-controller-7948496bcb-2ff68   1/1     Running   0          34m
nvidia-k8s-dra-driver-kubelet-plugin-z6lp5          1/1     Running   0          10m

体验NVIDIA Resource Driver

NVIDIA Resource Driver项目的demo目录下有一些示例yaml,这里选择以gpu-test2.yaml为例演示。这个例子演示了如何让一个pod两个容器共同使用1张GPU卡。该yaml文件内容如下:

# One pod, two containers
# Each asking for shared access to a single GPU

---
apiVersion: v1
kind: Namespace
metadata:
  name: gpu-test2

---
apiVersion: resource.k8s.io/v1alpha2
kind: ResourceClaimTemplate
metadata:
  namespace: gpu-test2
  name: gpu.nvidia.com
spec:
  spec:
    resourceClassName: gpu.nvidia.com

---
apiVersion: v1
kind: Pod
metadata:
  namespace: gpu-test2
  name: pod
spec:
  containers:
  - name: ctr0
    image: ubuntu:22.04
    command: ["bash", "-c"]
    args: ["nvidia-smi -L; sleep 9999"]
    resources:
      claims:
      - name: shared-gpu
  - name: ctr1
    image: ubuntu:22.04
    command: ["bash", "-c"]
    args: ["nvidia-smi -L; sleep 9999"]
    resources:
      claims:
      - name: shared-gpu
  resourceClaims:
  - name: shared-gpu
    source:
      resourceClaimTemplateName: gpu.nvidia.com

使用kubectl提交Pod。

kubectl apply -f demo/gpu-test2.yaml

查看Pod是否处于Running。

$ kubectl get po -n gpu-test2

NAME   READY   STATUS    RESTARTS   AGE
pod    2/2     Running   0          109m

查看pod两个容器使用的GPU卡是否为同一张卡。进入第一个容器执行nvidia-smi。

kubectl exec -ti pod -n gpu-test2 -c ctr0 -- nvidia-smi -L
GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-16d07e34-6b1e-0d26-73ef-3635fd7ed60e)

进入第二个容器执行nvidia-smi。

kubectl exec -ti pod -n gpu-test2 -c ctr1 -- nvidia-smi -L
GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-16d07e34-6b1e-0d26-73ef-3635fd7ed60e)

可以看到两个容器使用的GPU是同一张卡。

至于NVIDIA Resource Driver的其他功能的体验,可以参考demo目录的示例yaml文件。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
Kubernetes Cloud Native Docker
云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版
云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版
827 0
|
6月前
|
Kubernetes 应用服务中间件 Docker
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
|
2月前
|
Kubernetes 容器 Perl
Kubernetes网络插件体系及flannel基础
文章主要介绍了Kubernetes网络插件体系,特别是flannel网络模型的工作原理、配置和测试方法。
110 3
Kubernetes网络插件体系及flannel基础
|
3月前
|
Kubernetes Cloud Native 开发者
OpenKruise:Kubernetes的超级插件,一键解锁容器运行时操作的超能力!
【8月更文挑战第8天】在云原生领域,Kubernetes虽已成为容器编排的标准,但仍有限制,比如批量操作不便和高级调度功能缺失。OpenKruise是一款增强工具,提供CloneSet、Advanced StatefulSet等功能,既保持Kubernetes API特性又增加了扩展性,使Pod管理更灵活。可通过Helm安装OpenKruise,并使用CloneSet轻松实现批量部署。这类增强工具让开发者能更高效地突破原生Kubernetes的限制,预计未来将更加受到欢迎。
67 8
|
3月前
|
canal Kubernetes 负载均衡
在K8S中,优先优选哪个CNI插件?为何使用该插件?
在K8S中,优先优选哪个CNI插件?为何使用该插件?
|
3月前
|
存储 canal Kubernetes
在K8S中,什么是CNI?平时K8s集群常用什么网络插件?
在K8S中,什么是CNI?平时K8s集群常用什么网络插件?
|
6月前
|
Web App开发 Kubernetes 数据可视化
Kubernetes Dashboard 可视化插件部署 博主亲自实践可用
Kubernetes Dashboard 可视化插件部署 博主亲自实践可用
133 0
|
5月前
|
机器学习/深度学习 JSON Kubernetes
一篇文章讲明白k8s网络插件flannel模式剖析:vxlan、host
一篇文章讲明白k8s网络插件flannel模式剖析:vxlan、host
452 0
|
5月前
|
机器学习/深度学习 JSON Kubernetes
一篇文章讲明白k8s网络插件flannel模式剖析:vxlan、host
一篇文章讲明白k8s网络插件flannel模式剖析:vxlan、host
64 0
|
5月前
|
Kubernetes 容器 Perl
019.Kubernetes二进制部署插件dashboard
019.Kubernetes二进制部署插件dashboard