这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。

Kubernetes 1.26:设备管理器正式发布

作者: Swati Sehgal (Red Hat)

译者: Jin Li (UOS)

设备插件框架是在 Kubernetes v1.8 版本中引入的,它是一个与供应商无关的框架, 旨在实现对外部设备的发现、公布和分配,而无需修改核心 Kubernetes。 该功能在 v1.10 版本中升级为 Beta 版本。随着 Kubernetes v1.26 的最新发布, 设备管理器现已正式发布(GA)。

在 kubelet 中,设备管理器通过 Unix 套接字使用 gRPC 实现与设备插件的通信。 设备管理器和设备插件都充当 gRPC 服务器和客户端的角色,分别提供暴露的 gRPC 服务并进行连接。 设备插件提供 gRPC 服务,kubelet 连接该服务进行设备的发现、公布(作为扩展资源)和分配。 设备管理器连接到 kubelet 提供的 Registration gRPC 服务,以向 kubelet 注册自身。

请查阅文档中的示例, 了解一个 Pod 如何通过设备插件请求集群中暴露的设备。

以下是设备插件的一些示例实现:

自设备插件框架引入以来的重要进展

Kubelet APIs 移至 kubelet 暂存库

在 v1.17 版本中,面向外部的 deviceplugin API 包已从 k8s.io/kubernetes/pkg/kubelet/apis/ 移动到了 k8s.io/kubelet/pkg/apis/。有关此变更背后的更多详细信息, 请参阅 Move external facing kubelet apis to staging

设备插件 API 更新

新增了额外的 gRPC 端点:

  1. GetDevicePluginOptions 用于设备插件向 DeviceManager 传递选项,以指示是否支持 PreStartContainerGetPreferredAllocation 或其他将来的可选调用, 并可在向容器提供设备之前进行调用。
  1. GetPreferredAllocation 允许设备插件将优先分配信息传递给 DeviceManager, 使其能够将此信息纳入其分配决策中。DeviceManager 在 Pod 准入时向插件请求指定大小的优选设备分配,以便做出更明智的决策。 例如,在为容器分配设备时,指定设备间的约束条件以表明对最佳连接设备集合的偏好。
  1. 在注册阶段由设备插件指示时,PreStartContainer 会在每次容器启动之前被调用。 它允许设备插件在所请求的设备上执行特定的设备操作。 例如,在容器启动前对 FPGA 进行重新配置或重新编程。

引入这些更改的 PR 为:

  1. Invoke preStart RPC call before container start, if desired by plugin
  2. Add GetPreferredAllocation() call to the v1beta1 device plugin API

引入上述端点后,kubelet 中的设备管理器与设备管理器之间的交互如下所示:

展示设备插件框架,显示 kubelet 与设备插件之间的关系

设备插件框架概述

设备插件注册流程的语义变更

设备插件的代码经过重构,将 'plugin' 包独立于 devicemanager 包之外, 为引入 v1beta2 设备插件 API 做好了前期准备。 这将允许在 devicemanager 中添加支持,以便同时为多个设备插件 API 提供服务。

通过这次重构工作,现在设备插件必须在向 kubelet 注册之前开始提供其 gRPC 服务。 之前这两个操作是异步的,设备插件可以在启动其 gRPC 服务器之前注册自己,但现在不再允许。 更多细节请参考 PR #109016Issue #112395

动态资源分配

在 Kubernetes 1.26 中,受 Kubernetes 处理持久卷方式的启发, 引入了动态资源分配, 以满足那些具有更复杂资源需求的设备,例如:

  1. 将设备的初始化和分配与 Pod 生命周期解耦。
  2. 促进容器和 Pod 之间设备的动态共享。
  3. 支持自定义特定资源参数。
  4. 启用特定资源的设置和清理操作。
  5. 实现对网络附加资源的支持,不再局限于节点本地资源。

设备插件 API 目前已经稳定了吗?

不,设备插件 API 仍然不稳定;目前最新的可用设备插件 API 版本是 v1beta1。 社区计划引入 v1beta2 API,以便同时为多个插件 API 提供服务。 对每个 API 的调用都具有请求/响应类型,可以在不明确升级 API 的情况下添加对新 API 版本的支持。

除此之外,社区中存在一些提案,打算引入额外的端点 KEP-3162: Add Deallocate and PostStopContainer to Device Manager API