前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubelet从入门到放弃系列:GPU加持

Kubelet从入门到放弃系列:GPU加持

作者头像
zouyee
发布2021-03-06 22:52:39
1.1K0
发布2021-03-06 22:52:39
举报
文章被收录于专栏:Kubernetes GOKubernetes GO

友情提示:全文3090多文字,预计阅读时间5分钟

摘要

《Kubelet从入门到放弃系列》将对Kubelet组件由Linux基础知识到源码进行深入梳理。上一篇zouyee带各位看了Kubelet从入门到放弃:拓扑管理,其中提及设备插件,在本文<Kubelet从入门到放弃系列:与GPU齐飞>,今天zouyee跟段全峰童鞋为各位介绍Kubernetes如何利用Nvidia系列GPU,后续介绍Device Plugin的相关概念以及Kubelet组件源码逻辑。

一、需求说明

1.1 需求说明

在Kubernetes 1.8之前,用户使用GPU等设备时,推荐使用Accelerators Feature Gate的内置方式,延续Kubernetes的插件化的实现理念,各司其职,在Kubernetes 1.10版本后,引入设备插件框架,用户可以将系统硬件资源引入到Kubernetes生态。本文将介绍NVIDIA GPU如何安装部署,Device Plugins的相关介绍、工作机制和源码分析,包括插件框架、使用和调度GPU、和异常处理及优化等相关内容。

1.2 相关说明

在Kubernetes 1.10中Device Plugins升为Beta特性,在Kubernetes 1.8时,为了给第三方厂商通过插件化的方式将设备资源接入到Kubernetes,给容器提供Extended Resources。

通过Device Plugins方式,用户无需要改Kubernetes的代码,由第三方设备厂商开发插件,实现Kubernetes Device Plugins的相关接口即可(仔细想想,Kubernetes中的volume管理是否也是类似的逻辑?CSI、CNI、CRI?)。

目前Device Plugins典型实现有:

a) AMD GPU插件

b)Intel设备插件:GPU、FPGA和QuickAssist设备

c)KubeVirt用于硬件辅助的虚拟化设备插件

d)Nvidia提供的GPU插件

e)高性能低延迟RDMA卡插件

f)低延迟Solarflare万兆网卡驱动

g)SR-IOV网络设备插件

h)Xilinx FPGA设备插件

Kubelet启动Device plugins服务端,对应设备商启动Device Plugin服务,对外暴露几个gRPC Service提供服务,并通过/var/lib/kubelet/device-plugins/kubelet.sock与Kubelet通信。

二、部署介绍

2.1 部署说明

当前Nvidia GPU提供三种部署方式:docker方式、Containerd方式及Operator方式。

因docker后续不再内置,相关说明可以查看关于Kubernetes废弃内置docker CRI功能的说明,下文将主要介绍 Containerd部署,Operator方式后续单独成文,当前nvidia-container-toolkit已经支持containerd和cri-o两种部署方式,在接受containerd部署前,先说明前期遇到的相关问题:

a. 默认runtime设置

其中Kubelet问题描述:

代码语言:javascript
复制
Events:
  Type     Reason         Age                   From               Message
  ----     ------         ----                  ----               -------
  Normal   Scheduled      10m                   default-scheduler  Successfully assigned gpu-operator-resources/nvidia-device-plugin-daemonset-f99md to cl-gpu-md-0-f4gm6
  Warning  InspectFailed  10m (x3 over 10m)     kubelet            Failed to inspect image "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2": rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /run/containerd/containerd.sock: connect: connection refused"

其中Nvidia Device Plugin Daemonset某一个Pod相关错误,如下

代码语言:javascript
复制
# kubectl logs ‐f nvidia‐device‐plugin‐daemonset‐q9svq ‐nkube‐system
2021/02/11 01:32:29 Loading NVML
2021/02/11 01:32:29 Failed to initialize NVML: could not load NVML library.
2021/02/11 01:32:29 If this is a GPU node, did you set the docker default runtime to `nvidia`?
2021/02/11 01:32:29 You can check the prerequisites at: https://github.com/NVIDIA/k8s-device-plugin#prerequisites
2021/02/11 01:32:29 You can learn how to set the runtime at: https://github.com/NVIDIA/k8s-device-plugin#quick-start
2021/02/11 01:32:29 If this is not a GPU node, you should set up a toleration or nodeSelector to only deploy this plugin on GPU nodes

该问题由于containerd的配置文件containerd.toml未将default_runtime_name = "runc"修改为default_runtime_name = "nvidia",相关问题:https://github.com/NVIDIA/gpu-operator/issues/143

b. kubelet cgroup driver配置

相关问题:https://github.com/NVIDIA/libnvidia-container/issues/119

在kubelet配置的cgroup driver为systemd时,Nvidia的container prestart hook在处理cgroup路径逻辑与containerd不一致。

代码语言:javascript
复制
containerd[76114]: time="2020-12-04T08:52:13.029072066Z" level=error msg="StartContainer for "7a1453c6e7ab8af7395ccc8dac5efcffa94a0834aa7b252e1dcd5b51f92bf13e" failed" error="failed to create containerd task: OCI runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: Running hook #0:: error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: mount error: open failed: /sys/fs/cgroup/devices/system.slice/containerd.service/kubepods-pod80540e95304d8cece2ae2afafd8b8976.slice/devices.allow: no such file or directory: unknown"

解决方案为升级libnvidia-container或者container-toolkit。

接下来,介绍部署相关内容。

2.2 Containerd方式

‍‍‍ 1)版本说明

软件

版本说明

CentOS

7

内核

4.19.25

GPU型号

Tesla T4

driver版本

418.39

CUDA版本

10.1

K8S

1.18.5

Nvidia Device Plugin

0.7.3

Containerd

v1.4.3

runc‍‍‍‍

1.0.0-rc1

2)安装

注:下文为内网离线部署,若各位在联网环境下,只需参考部署步骤及部署配置即可

a. 安装驱动

代码语言:javascript
复制
$ tar ‐zxvf gpu.tar.gz 
## 安装依赖 
$ cd gpu/runtime 
$ tar ‐zxvf dependency.tar.gz 
$ cd dependency 
## 查看是否支持CUDA的Nvidia的GPU 
$ cd ./lspci/ 
$ yum localinstall ‐y *.rpm 
$ lspci | grep ‐i nvidia ## 安装devel 
$ cd ../devel 
$ yum localinstall ‐y *.rpm 
## 安装gcc $ cd ../gcc 
$ yum localinstall ‐y *.rpm 
## 卸载nouveau驱动 
$ lsmod | grep nouveau 
$ rmmod nouveau 
## 安装驱动,过程见下面附的图片。如果要更新驱动,从https://developer.nvidia.com/cuda‐75‐downloads‐ archive下载 
$ cd ../../../driver 
$ sh cuda_10.1.105_418.39_linux.run ## 测试驱动,有如下输出则正常安装

结果验证

代码语言:javascript
复制
$ nvidia‐smi

附:安装驱动图

(1) 输入accept,回车

(2) 选择install,回车

2)配置Containerd

代码语言:javascript
复制
## 更新runc,下载地址https://github.com/opencontainers/runc/releases 
$ cd ../runtime 
$ cp runc /usr/bin/ 
## 更新containerd,下载地址 https://github.com/containerd/containerd/releases 
$ tar ‐zxvf containerd‐1.4.3‐linux‐amd64.tar.gz 
$ cp bin/* /usr/bin/ 
## 安装nvidia‐container‐runtime,yum源https://nvidia.github.io/nvidia‐docker/centos7/nvidia‐ docker.repo,yum安装:yum install ‐y nvidia‐container‐runtime $ tar ‐zxvf nvidia‐container‐runtime.tar.gz 
$ cd nvidia‐container‐runtime 
$ yum localinstall ‐y *.rpm
修改containerd启动参数
代码语言:javascript
复制
# 配置containerd的参数 
$ mkdir /etc/containerd/ 
$ vi /etc/containerd/config.toml 
# 配置containerd.service 
$ vi /usr/lib/systemd/system/containerd.service 
$ systemctl daemon‐reload 
$ systemctl restart containerd 
# 配置crictl 
$ tar ‐zxvf crictl‐v1.18.0‐linux‐amd64.tar.gz 
$ mv crictl /usr/bin/ 
$ vi /etc/profile alias crictl='crictl ‐‐runtime‐endpoint unix:///run/containerd/containerd.sock' 
$ source /etc/profile 
# 测试containerd和nvidia‐container‐runtime安装是否成功 
$ cd test‐image 
$ ctr images import cuda‐vector‐add_v0.1.tar 
$ ctr images push ‐‐plain‐http registry.paas/cmss/cuda‐vector‐add:v0.1

执行检验

代码语言:javascript
复制
ctr run ‐t ‐‐gpus 0 registry.paas/cmss/cuda‐vector‐add:v0.1 cp nvidia‐smi
结果如下

清理容器

代码语言:javascript
复制
ctr c rm cp

配置config.toml

执行containerd config default > /etc/containerd/config.toml生成配置,并做如下修改:

注意:如上所述,1)default_runtime_name值为nvidia,2)新增一个runtimes 3)若有内部镜像仓库,可修改docker.io为内部仓库名称

配置containerd.service

代码语言:javascript
复制
[Unit] 
Description=containerd container runtime 
Documentation=https://containerd.io After=network.target

[Service] 
ExecStartPre=‐/sbin/modprobe overlay 
ExecStart=/usr/bin/containerd 
KillMode=process 
Delegate=yes 
LimitNOFILE=1048576 
# Having non‐zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container‐local accounting. LimitNPROC=infinity 
LimitCORE=infinity 
TasksMax=infinity 
[Install] 
WantedBy=multi‐user.target    

c. 部署Device Plugin

在部署完Kubernetes集群后,修改kubelet运行时配置:

代码语言:javascript
复制
$ vi /apps/conf/kubernetes/kubelet.env ‐‐container‐runtime=remote ‐‐container‐runtime‐endpoint=unix:///run/containerd/containerd.sock
代码语言:javascript
复制
$ cd device‐plugin 
$ docker load ‐i k8s‐device‐plugin_v0.7.3.tar 
$ docker push
// https://github.com/NVIDIA/k8s-device-plugin/tree/master/deployments/static
$ kubectl apply ‐f nvidia‐device‐plugin.yml 
$ kubectl logs ‐f nvidia‐device‐plugin‐daemonset‐q9svq ‐nkube‐system 
2021/02/08 06:32:36 Loading NVML 2021/02/08 06:32:42 Starting FS watcher. 2021/02/08 06:32:42 Starting OS watcher. 2021/02/08 06:32:42 Retreiving plugins. 2021/02/08 06:32:42 Starting GRPC server for 'nvidia.com/gpu' 2021/02/08 06:32:42 Starting to serve 'nvidia.com/gpu' on /var/lib/kubelet/device‐ plugins/nvidia‐gpu.sock 2021/02/08 06:32:42 Registered device plugin for 'nvidia.com/gpu' with Kubelet

d. 功能测试

代码语言:javascript
复制
$ cd test‐image 
# 启动测试pod 
$ kubectl apply ‐f demo.yml
// https://github.com/NVIDIA/gpu-operator/blob/master/tests/gpu-pod.yaml
$ kubectl logs ‐f cuda‐vector‐add 
[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

未完,待续.

三、参考资料

1. https://kubernetes.io/zh/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/

2.https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/device-plugin.md

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DCOS 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • b. kubelet cgroup driver配置
  • 2.2 Containerd方式
  • 修改containerd启动参数
  • 结果如下
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档