我的NVIDIA开发者之旅——NVIDIA云原生技术
时间:2022-10-25 07:00:03
NVIDIA云原生技术:耐心看完受益匪浅
- 第一篇-》NVIDIA云原生技术
-
- 【1】NVIDIA容器工具包
- 【2】GPU操作员
- 【3】带GPU的Kubernetes
-
- 【3.1】安装Kubernetes
"我的NVIDIA开发者之旅 | 征文活动正在进行中…
第一篇-》NVIDIA云原生技术
NVIDIA云原生技术
使开发人员能够使用Docker
和Kubernetes
构建和运行GPU
加速容器。
【1】NVIDIA容器工具包
概观
NVIDIA容器工具包
允许用户构建和运行GPU加速
容器。该工具包括图书馆和实用程序在容器运行时自动配置容器NVIDIAGPUs
。
NVIDIA在生态系统中,容器工具包支持不同的容器引擎-[码头工人], [LXC], [波德曼]等等。跟随[用户指南]使用这些引擎GPU容器。
体系结构
这个[架构概述]描述
NVIDIA容器工具包
技术架构和软件包装。
安装指南
这个[安装指南]展示了不同的方式
Linux发行版
安装在平台上NVIDIA容器工具包
。
故障排除指南
列出[解决纠纷]
NVIDIA Container Toolkit
一些已知问题和一般故障排除步骤。
【2】GPU操作员
概观
Kubernetes
访问特殊硬件资源,如NVIDIA GPUs、NIC、Infiniband适配器
以及其他设备[设备插件框架]。然而,具有这些硬件资源的节点的配置和管理需要配置多个软件组件,如驱动程序、容器运行或其他库
,这很难,也很容易出错。NVIDIA GPU操作员
使用[运营商框架]Kubernetes
中自动管理配置GPU所需的所有NVIDIA软件组件。这些组件包括NVIDIA驱动程序(支持)CUDA
)、用于GPU
的Kubernetes
设备插件[NVIDIA德中会展经济协会以监控等为基础,自动节点标谷蛋白饮食。
【3】带GPU的Kubernetes
【3.1】安装Kubernetes
介绍
Kubernetes
容器化应用程序的自动部署、扩展和管理开源平台
。Kubernetes包括对GPU的支持和对Kubernetes所以用户可以轻松配置和使用GPU资源来加速AI和HPC工作负载
。
安装的方法有很多NVIDIA支持组件上游Kubernetes,如
驱动程序、插件和操作
。
开始操作:
选项1:使用[深度操作]
选项2:使用[Kubeadm安装]Kubernetes
选项2-a:使用英伟达GPU]运营商自动化/管理NVIDIA部署软件组件
选项2-b:将NVIDIA软件组件设置为[先决条件]
选项1:使用DeepOps安装Kubernetes
使用
DeepOps
包含许多工作节点的集群来自动化部署。DeepOps是一个ansible脚本
它可以自动部署在您的节点上Kubernetes、Slurm或两者的混合。它还将安装必要的GPU驱动程序,用于Docker的NVIDIA容器工具包(nvidia-docker2
),以及GPU其他加速工作的依赖项目。它包装了NVIDIA GPUs最佳实践可根据需要定制或作为单独的组件运行。
1.通过以下步骤使用以下步骤DeepOps安装Kubernetes:
选择要部署的预配节点。这是操作
DeepOps Ansible脚本
通常是连接到目标集群的开发笔记本电脑。在此供应节点上,使用以下命令克隆DeepOps存储库
:
git clone https://github.com/NVIDIA/deepops.git
cd deepops \ && git checkout tags/20.10
若使用不清楚release标签将使用最新的开发代码,而不是官方版本。
3.按照中间的说明操作[DeepOps Kubernetes安装部署指南Kubernetes。
选项2:使用Kubeadm安装Kubernetes
对于脚本较少的方法,特别是对于较小的集群或想要理解的组成Kubernetes可用于集群组件的地方
Kubeadm
。
Kubernetes集群
由主节点和工作节点组成。主节点运行Kubernetes控制平面组件允许您的集群正常运行。这些组件包括API服务器(前端kubectlCLI
),主节点(存储集群状态)等。
使用
纯CPU(无GPU)主节点
,平面组件运行控制:调度程序、API控制器管理器。控制面板组件可能对你有好处CPU相反,密集型任务会产生一些影响,CPU或HDD/SSD密集型组件也会影响您的控制面板组件。随着
kubeadm
,本文将介绍安装单节点Kubernetes集群步骤(在此,我们取消了控制平面的限制,使其能够运行GPU pods),但是集群可以通过添加节点轻松扩展。>
步骤0:开始之前
在继续安装组件之前,检查所有Kubernetes[先决条件]已经满足了。这些先决条件包括:
【1】 检查
网络适配器
和所需的端口
【2】禁用节点上的交换,以便kubelet
可以正常工作
【3】安装受支持的容器运行时,如Docker、containerd或CRI-O
根据您的Linux发行版,请参考以下步骤:
乌班图LTS
CentOS
乌班图LTS¶
本节提供了在
Ubuntu 18.04和20.04 LTS发行版
上设置K8s
的步骤。
步骤1:安装容器引擎
NVIDIA支持使用Docker和其他CRI兼容运行时运行GPU容器,例如集装箱d或者叫CRI-O。
码头工人 集装箱d |
|
按照中的步骤操作[向导安装Docker] |
步骤2:安装Kubernetes组件
首先,安装一些依赖项:
sudo apt-get update \
&& sudo apt-get install -y apt-transport-https curl
添加包存储库密钥:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
存储库:
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF
更新软件包列表并安装库伯莱:
sudo apt-get update \
&& sudo apt-get install -y -q kubelet kubectl kubeadm
!注意
如果你在使用containerd作为CRI运行时,然后按照以下步骤操作:
【1】 为配置cgroup驱动程序kubelet:
sudo mkdir -p /etc/systemd/system/kubelet.service.d/
sudo cat << EOF | sudo tee /etc/systemd/system/kubelet.service.d/0-containerd.conf [Service] Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver='systemd'" EOF
【2】重新启动kubelet:
sudo systemctl daemon-reload \
&& sudo systemctl restart kubelet
禁用交换
sudo swapoff -a
和
init
使用kubeadm
:
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
使用Kubeadm完成配置设置:
mkdir -p $HOME/.kube \
&& sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config \
&& sudo chown $(id -u):$(id -g) $HOME/.kube/config
步骤3:配置网络
现在,使用Calico设置网络:
$ kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
解除对控制平面的限制,以便它可以用于在我们简单的单节点集群中调度GPU pods:
$ kubectl taint nodes --all node-role.kubernetes.io/master-
您的集群现在应该可以调度容器化的应用程序了。
CentOS
按照本节中的步骤在CentOS 7/8上设置K8s。
!注意
如果您在云IaaS平台(如EC2)上使用CentOS 7/8,那么您可能需要进行一些额外的设置,如下所示:
【1】为您的EC2地区选择官方CentOS图像:https://wiki.centos.org/Cloud/AWS
【2】安装一些必备组件:
CentOS 8 |
CentOS 7 |
sudo dnf install -y tar bzip2 make automake gcc gcc-c++ \
pciutils elfutils-libelf-devel libglvnd-devel \
iptables firewalld bind-utils \
vim wget
【3】更新正在运行的内核,以确保您运行的是最新的更新
CentOS 8 |
CentOS 7 |
sudo dnf update -y
【4】重启你的虚拟机
sudo reboot
步骤0:配置系统
禁用新功能
为了成功安装NVIDIA驱动程序,必须首先禁用新驱动程序。
确定
nouveau驱动程序
已加载:
$ lsmod | grep -i nouveau
在以下位置创建文件
/etc/modprobe.d/blacklist-nouveau.conf
包含以下内容:
blacklist nouveau
options nouveau modeset=0
重新生成内核initramfs:
sudo dracut --force
继续下一步之前,请重新启动系统。
对于本节的剩余部分,我们将遵循使用的一般步骤[kubeadm]。此外,为了方便起见,让我们进入一个互动
sudo
会话,因为其余大多数命令都需要root权限:
sudo -i
禁用SELinux
setenforce 0 \
&& sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
桥接流量和iptables
如中所述kubedadm文档,请确保br_netfilter模块已加载:
$ modprobe br_netfilter
确保
net.bridge.bridge-nf-call-iptables
已正确配置:
cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
并重新启动
sysctl
配置:
sysctl --system
防火墙和所需端口
网络插件要求在控制平面和工作节点上打开某些端口。看到这个了吗[桌子]有关这些端口号用途的更多信息。
确保
firewalld
正在运行:
$ systemctl status firewalld
如果需要,开始
firewalld
:
$ systemctl --now enable firewalld
现在打开端口:
firewall-cmd --permanent --add-port=6443/tcp \
&& firewall-cmd --permanent --add-port=2379-2380/tcp \
&& firewall-cmd --permanent --add-port=10250/tcp \
&& firewall-cmd --permanent --add-port=10251/tcp \
&& firewall-cmd --permanent --add-port=10252/tcp \
&& firewall-cmd --permanent --add-port=10255/tcp
还需要添加
docker0
接口到公共区域,并允许docker0
入口和出口:
`CentOS 8 | CentOS 7`
$ nmcli connection modify docker0 connection.zone public \
&& firewall-cmd --zone=public --add-masquerade --permanent \
&& firewall-cmd --zone=public --add-port=443/tcp
重新加载
firewalld
配置和dockerd
为使设置生效:
$ firewall-cmd --reload \
&& systemctl restart docker
或者,在我们安装Kubernetes控制平面之前,使用一个简单的
ping命令
:
$ docker run busybox ping google.com
禁用交换
为了提高性能,请在系统上禁用交换:
$ swapoff -a
步骤1:安装Docker
按照中的步骤操作[向导]在CentOS 7/8上安装Docker。
步骤2:安装Kubernetes组件
将网络存储库列表添加到软件包管理器配置中:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
安装组件:
`CentOS 8 | CentOS 7`
$ dnf install -y kubelet kubectl kubeadm
确保
kubelet
在系统重新启动时启动:
$ systemctl --now enable kubelet
现在使用kubeadm要初始化控制平面:
kubeadm init --pod-network-cidr=192.168.0.0/16
此时,您可以随意退出互动
sudo
我们开始的那个环节。
配置目录
要开始使用群集,请以普通用户身份运行以下命令:
mkdir -p $HOME/.kube \
&& sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config \
&& sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果您正在使用一个简单的集群(或者只是测试),您可以解开控制平面节点,以便它也可以运行容器:
$ kubectl taint nodes --all node-role.kubernetes.io/master-
此时,您的集群将如下所示:
$ kubectl get pods -A
`NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-f9fd979d6-46hmf 0/1 Pending 0 23s kube-system coredns-f9fd979d6-v7v4d 0/1 Pending 0 23s kube-system etcd-ip-172-31-54-109.ec2.internal 0/1 Running 0 38s kube-system kube-apiserver-ip-172-31-54-109.ec2.internal 1/1 Running 0 38s kube-system kube-controller-manager-ip-172-31-54-109.ec2.internal 0/1 Running 0 37s kube-system kube-proxy-xd5zg 1/1 Running 0 23s kube-system kube-scheduler-ip-172-31-54-109.ec2.internal 0/1 Running 0 37s`
步骤3:配置网络
出于本文的目的,我们将使用Calico作为网络插件来配置Kubernetes集群中的网络。由于一个[问题]使用CentOS上的Calico和iptables,让我们在部署插件之前修改配置。
下载calico
配置:
curl -fOSsL https://docs.projectcalico.org/manifests/calico.yaml
并将以下配置选项添加到环境部分:
- name: FELIX_IPTABLESBACKEND
value: "NFT"
保存修改后的文件,然后部署插件:
$ kubectl apply -f ./calico.yaml
几分钟后,您可以看到网络已经配置完毕:
`NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5c6f6b67db-wmts9 1/1 Running 0 99s kube-system calico-node-fktnf 1/1 Running 0 100s kube-system coredns-f9fd979d6-46hmf 1/1 Running 0 3m22s kube-system coredns-f9fd979d6-v7v4d 1/1 Running 0 3m22s kube-system etcd-ip-172-31-54-109.ec2.internal 1/1 Running 0 3m37s kube-system kube-apiserver-ip-172-31-54-109.ec2.internal 1/1 Running 0 3m37s kube-system kube-controller-manager-ip-172-31-54-109.ec2.internal 1/1 Running 0 3m36s kube-system kube-proxy-xd5zg 1/1 Running 0 3m22s kube-system kube-scheduler-ip-172-31-54-109.ec2.internal 1/1 Running 0 3m36s`
要验证网络是否已成功设置,让我们使用
multitool
容器:
$ kubectl run multitool --image=praqma/network-multitool --restart Never
然后运行一个简单的
ping命令
来确保可以正确检测到DNS服务器
:
kubectl exec multitool -- sh -c 'ping google.com'
PING google.com (172.217.9.206) 56(84) bytes of data.
64 bytes from iad30s14-in-f14.1e100.net (172.217.9.206): icmp_seq=1 ttl=53 time=0.569 ms
64 bytes from iad30s14-in-f14.1e100.net (172.217.9.206): icmp_seq=2 ttl=53 time=0.548 ms
步骤4:安装NVIDIA软件
至此,您应该有一个工作的Kubernetes控制平面和连接到集群的worker节点。我们可以继续在工作节点上配置NVIDIA软件。如本文开头所述,有两种选择:
安装NVIDIA依赖项
Kubernetes集群中的GPU worker节点需要启用以下组件:
【1】NVIDIA驱动程序
【2】NVIDIA容器工具包
【3】NVIDIA Kubernetes设备插件(以及可选的GPU功能发现插件)
【4】(可选)DCGM出口商收集GPU遥测数据,并集成到Prometheus等监控堆栈中
让我们走完这些步骤。
安装NVIDIA驱动程序
本节概述了使用安装驱动程序的步骤
apt
LTS Ubuntu上的软件包管理器。
注意
有关设置NVIDIA驱动程序的完整说明,请访问快速入门指南[https://docs . NVIDIA . com/datacenter/Tesla/Tesla-installation-notes/index . html]。该指南涵盖了成功安装驱动程序所需的大量预安装要求和受支持Linux发行版的步骤。
为当前运行的内核安装内核头文件和开发包:
sudo apt-get install linux-headers-$(uname -r)
设置CUDA网络存储库,并确保CUDA网络存储库上的包优先于规范存储库:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed -e 's/\.//g') \
&& wget https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-$distribution.pin \
&& sudo mv cuda-$distribution.pin /etc/apt/preferences.d/cuda-repository-pin-600
安装CUDA存储库GPG密钥:
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/7fa2af80.pub \
&& echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64 /" | sudo tee /etc/apt/sources.list.d/cuda.list
更新
apt
存储库缓存并使用cuda-drivers
或者cuda-drivers-
元包。使用--no-install-recommends
不依赖于X包的精简驱动安装选项。这对于云实例上的无头安装特别有用:
sudo apt-get update \
&& sudo apt-get -y install cuda-drivers
安装NVIDIA容器工具包(nvidia-docker2
)
首先,设置
stable
NVIDIA运行时和GPG密钥
的存储库:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
根据容器引擎的不同,您可能需要使用不同的包。
码头工人
|
集装箱d
安装nvidia-docker2
更新程序包列表后的程序包(及其依赖项):
sudo apt-get update \
&& sudo apt-get install -y nvidia-docker2
因为
Kubernetes
不支持--gpusDocker
的选项nvidia
运行时应该设置为GPU节点上Docker的默认容器运行时。这可以通过添加default-runtime
行插入Docker守护进程配置文件,该文件通常位于系统的/etc/docker/daemon.json
:
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
设置默认运行时后,重新启动Docker守护程序以完成安装:
sudo systemctl restart docker
此时,可以通过运行一个基本的
CUDA容器
来测试工作设置:
sudo docker run --rm --gpus all nvidia/cuda:11.0-base 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 |
+-----------------------------------------------------------------------------+
安装NVIDIA设备插件
要在Kubernetes中使用GPU [NVIDIA设备插件]是必需的。NVIDIA设备插件是一个daemonset,它自动枚举集群每个节点上的GPU数量,并允许pods在GPU上运行。
部署设备插件的首选方法是使用
helm
。首先,安装头盔:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \
&& chmod 700 get_helm.sh \
&& ./get_helm.sh
添加
nvidia-device-plugin helm
存储库:
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin \
&& helm repo update
部署设备插件:
helm install --generate-name nvdp/nvidia-device-plugin
有关部署daemonset时用户可配置的更多选项,请[参考文件]
此时,所有的吊舱都应展开:
$ kubectl get pods -A
`NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5fbfc9dfb6-2ttkk 1/1 Running 3 9d kube-system calico-node-5vfcb 1/1 Running 3 9d kube-system coredns-66bff467f8-jzblc 1/1 Running 4 9d kube-system coredns-66bff467f8-l85sz 1/1 Running 3 9d kube-system etcd-ip-172-31-81-185 1/1 Running 4 9d kube-system kube-apiserver-ip-172-31-81-185 1/1 Running 3 9d kube-system kube-controller-manager-ip-172-31-81-185 1/1 Running 3 9d kube-system kube-proxy-86vlr 1/1 Running 3 9d kube-system kube-scheduler-ip-172-31-81-185 1/1 Running 4 9d kube-system nvidia-device-plugin-1595448322-42vgf 1/1 Running 2 9d`
要测试CUDA作业是否可以部署,运行一个示例CUDA
vectorAdd
应用:下面显示了
pod规格
以供参考,它要求1个GPU
:
apiVersion: v1
kind: Pod
metadata:
name: gpu-operator-test
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
image: "nvidia/samples:vectoradd-cuda10.2"
resources:
limits:
nvidia.com/gpu: 1
将此
podspec
另存为gpu-pod.yaml
。现在,部署应用程序:
$ kubectl apply -f gpu-pod.yaml
检查日志以确保应用程序成功完成:
$ kubectl get pods gpu-operator-test
NAME READY STATUS RESTARTS AGE
gpu-operator-test 0/1 Completed 0 9d
并检查日志
gpu-operator-testpod
:
$ kubectl logs gpu-operator-test
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done