继CRI CNI CSI后,CNCF对三方设备的管理也将推行标准化接口了

第三方设备在runtime和编排系统下的现状如何?

Kubernetes支持Device Plugins

Nomad有自己的Device Plugins概念

Docker有一个in tree plugin机制

Podman有一个hooks概念

LXC有自己的钩子概念

Singularity(HPC运行时)有一个plugins的概念

还有些运行时几乎不支持第三方设备(例如:gVisor)

...

还有更多!

 

为什么说

“-- device  /dev/myDevice”是不够的?

 

在Linux系统下,一些简单的设备只需要能上报到节点即可。

然而,更多复杂的设备需要更加复杂的操作:

  • 需要上报到更多的设备节点

  • 需要检查容器和设备的兼容性(设备是否支持在该容器中运行)

  • 执行一些runtime的特殊操作

  • 执行一些设备的特殊操作(GPU内存释放或重新配置FPGA)

 

为什么

需要定义容器设备接口规范?

 

  • 用户体验不一致:

在runtime和编排系统上的体验各不相同(即使使用的是相同的runtime);

某些设备不支持特定的runtime。

  • 供应商体验更糟糕:

设备插件不能兼容所有runtime,无法直接切换;

维护成本高(大量的时间花费在特性兼容运行时上)。

 

使用场景

 

  • 使用场景1:Intel FPGA

英特尔FPGA被用于数据中心和工作站的许多不同使用场景(嵌入式SRAM、高速I/O、逻辑块等)

需要在容器中执行的操作:

1、挂载控制设备

2、以正确的方式重新配置FPGA,以免用户误操作

当前使用CRIO在容器中注入OCI钩子

 

  • 使用场景2:Mellanox NICs

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)填充程序

 

Container Device Interface

 

  • 具备的能力:

基于JSON规范的CNI模型

描述计算机上可用的设备

描述运行时为使设备对容器可用而必须执行的操作

描述运行时应实现的CLI示例

  • 缺失的能力:

处理设备资源管理,例如:使用已被其他容器使用的设备

 

CDI实例(simple)

$ 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 …

 

CDI实例(Advanced 1/3)

$ 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”:指定在为容器请求设备时要执行的操作。

 

CDI实例(Advanced 2/3)

$ 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。

 

CDI实例(Advanced 3/3)

$ mkdir /etc/cdi

$ cat > /etc/cdi/vendor-docker.json <

{

  "cdiVersion": "0.2.0",

  "kind": "vendor.com/device",

  "runtime": "docker",

  "cdiDevices": [ ... ]

}

EOF

 

runtime允许指定。

允许对不同的运行时使用不同的策略。

 

架构设计

Device Plugin

继CRI CNI CSI后,CNCF对三方设备的管理也将推行标准化接口了_第1张图片

 

1.device plugin向kubelet注册资源socket

2.起grpc服务端

3.上报设备资源

4.调用api server将设备资源同步到节点

 

Kubernetes如何使用CDI?

继CRI CNI CSI后,CNCF对三方设备的管理也将推行标准化接口了_第2张图片

 

1、k8s device plugin注册上报设备资源给kubelet

2、runtime起容器时调用CDI定义的接口执行相应操作

 

总结:

 

以k8s device plugin为例,CDI的优势有哪些?

1、统一容器设备接口规范(CDI)

2、支持device plugin向其他编排系统和runtime进行迁移

3、支持容器请求设备时执行指定操作

4、支持设备容器mounts和hooks

5、支持指定自定义runtime

6、支持解绑供应商指定runtime,可以通过mounts和hooks解决(nvidia-container-runtime)

 

尚待解决的地方

相同厂商的GPU设备,device plugin不支持指定具体型号进行挂载

你可能感兴趣的:(继CRI CNI CSI后,CNCF对三方设备的管理也将推行标准化接口了)