Kubernetes支持Device Plugins
Nomad有自己的Device Plugins概念
Docker有一个in tree plugin机制
Podman有一个hooks概念
LXC有自己的钩子概念
Singularity(HPC运行时)有一个plugins的概念
还有些运行时几乎不支持第三方设备(例如:gVisor)
...
还有更多!
在Linux系统下,一些简单的设备只需要能上报到节点即可。
然而,更多复杂的设备需要更加复杂的操作:
需要上报到更多的设备节点
需要检查容器和设备的兼容性(设备是否支持在该容器中运行)
执行一些runtime的特殊操作
执行一些设备的特殊操作(GPU内存释放或重新配置FPGA)
用户体验不一致:
在runtime和编排系统上的体验各不相同(即使使用的是相同的runtime);
某些设备不支持特定的runtime。
供应商体验更糟糕:
设备插件不能兼容所有runtime,无法直接切换;
维护成本高(大量的时间花费在特性兼容运行时上)。
英特尔FPGA被用于数据中心和工作站的许多不同使用场景(嵌入式SRAM、高速I/O、逻辑块等)
需要在容器中执行的操作:
1、挂载控制设备
2、以正确的方式重新配置FPGA,以免用户误操作
当前使用CRIO在容器中注入OCI钩子
Mellanox提供高性能Ethernet和Infiniband NIC用于许多数据中心和高性能集群
需要在容器中执行的操作(Linux):
1、挂载设备节点
2、挂载userland库从runtime命名空间到容器中
3、将userland库从运行时命名空间装载到容器中
4、更新sysfs
5、配置容器网络(CNI)
6、更多示例:
https://github.com/NVIDIA/enroot/blob/master/conf/hooks/99-mellanox.sh
使用场景3:NVIDIA GPUs
NVIDIA提供的GPU可用于云上加速计算密集型操作。例如:深度学习、机器学习、高性能计算、数据可视化等
需要在容器中执行的操作(Linux):
1、挂载设备节点
2、挂载userland库从runtime命名空间到容器中
3、挂载Unix套接字(例如:persistenced、MPS、Xorg…)
4、更新procfs条目以隐藏未隔离的gpu
5、执行容器和GPU之间的兼容性检查
6、更多
(https://docs.google.com/document/d/10EGjF1nEGUD5060dJ-ZcJI2w7Ob4CLCvcn1lzKW6I4o/edit)
当前使用CRIO向OCI钩子或Docker的默认运行时注入运行时(runc)填充程序
具备的能力:
基于JSON规范的CNI模型
描述计算机上可用的设备
描述运行时为使设备对容器可用而必须执行的操作
描述运行时应实现的CLI示例
缺失的能力:
处理设备资源管理,例如:使用已被其他容器使用的设备
$ mkdir /etc/cdi
$ cat > /etc/cdi/vendor.json < { "cdiVersion": "0.2.0", "kind": "vendor.com/device", "cdiDevices": [ { "name": "myDevice", "containerSpec": { "devices": [ {"hostPath": "/dev/card1", "containerPath": "/dev/card1"} {"hostPath": "/dev/card-render1", "containerPath": "/dev/card-render1"} ], } } ] EOF $ alias runtime=podman/docker/… # Verbose $ runtime run --device vendor.com/device=myDevice --device vendor.com/device=myDevice2 … # Less verbose, through inferring the vendor from the device name $ runtime run --device myDevice … # Special case $ runtime run --device vendor.com/device=all … $ mkdir /etc/cdi $ cat > /etc/cdi/vendor.json < { "cdiVersion": "0.2.0", "kind": "vendor.com/device", "cdiDevices": [...], "containerSpec": { "devices": [ {"hostPath": "/dev/vendorctl", "containerPath": "/dev/vendorctl"} ] } EOF “containerSpec”:指定在为容器请求设备时要执行的操作。 $ mkdir /etc/cdi $ cat > /etc/cdi/vendor.json < { "cdiVersion": "0.2.0", "kind": "vendor.com/device", "cdiDevices": [...], "containerSpec": { "mounts": [ {"hostPath": "/bin/vendorBin", "containerPath": "/bin/vendorBin"}, {"hostPath": "/usr/lib/libVendor.so.0", "containerPath": "/usr/lib/libVendor.so"} ], "hooks": [ {"create-container": {"path": "/bin/vendor-hook"} }, {"start-container": {"path": "/usr/bin/ldconfig"} } ] } EOF “mounts”和“hooks”允许从runtime namespace挂载文件以及运行OCI钩子。 例如,在启动容器之前运行ldconfig。 $ mkdir /etc/cdi $ cat > /etc/cdi/vendor-docker.json < { "cdiVersion": "0.2.0", "kind": "vendor.com/device", "runtime": "docker", "cdiDevices": [ ... ] } EOF runtime允许指定。 允许对不同的运行时使用不同的策略。 1.device plugin向kubelet注册资源socket 2.起grpc服务端 3.上报设备资源 4.调用api server将设备资源同步到节点 1、k8s device plugin注册上报设备资源给kubelet 2、runtime起容器时调用CDI定义的接口执行相应操作 1、统一容器设备接口规范(CDI) 2、支持device plugin向其他编排系统和runtime进行迁移 3、支持容器请求设备时执行指定操作 4、支持设备容器mounts和hooks 5、支持指定自定义runtime 6、支持解绑供应商指定runtime,可以通过mounts和hooks解决(nvidia-container-runtime) 相同厂商的GPU设备,device plugin不支持指定具体型号进行挂载CDI实例(Advanced 1/3)
CDI实例(Advanced 2/3)
CDI实例(Advanced 3/3)
架构设计
Device Plugin
Kubernetes如何使用CDI?
总结:
以k8s device plugin为例,CDI的优势有哪些?
尚待解决的地方