--- api_metadata: apiVersion: "resource.k8s.io/v1alpha3" import: "k8s.io/api/resource/v1alpha3" kind: "DeviceClass" content_type: "api_reference" description: "DeviceClass 是由供应商或管理员提供的资源,包含设备配置和选择算符。" title: "DeviceClass v1alpha3" weight: 2 --- `apiVersion: resource.k8s.io/v1alpha3` `import "k8s.io/api/resource/v1alpha3"` ## DeviceClass {#DeviceClass} DeviceClass 是由供应商或管理员提供的资源,包含设备配置和选择算符。 它可以在申领的设备请求中被引用,以应用预设值。作用域为集群范围。 这是一个 Alpha 阶段的资源类别,需要启用 DynamicResourceAllocation 特性门控。
- **apiVersion**: resource.k8s.io/v1alpha3 - **kind**: DeviceClass - **metadata** (}}">ObjectMeta) 标准的对象元数据。 - **spec** (}}">DeviceClassSpec),必需 spec 定义什么可以被分配以及如何进行配置。 此字段是可变更的。消费者必须准备好应对随时会变更的类,变更的原因可能是被更新或被替换。 申领分配是基于分配之时类中所设置的内容而确定的。 变更 spec 会让 metadata.generation 编号自动递增。 ## DeviceClassSpec {#DeviceClassSpec} DeviceClassSpec 在 DeviceClass 中用于定义可以分配的资源及其配置方式。
- **config** ([]DeviceClassConfiguration) **原子:将在合并期间被替换** config 定义通过此类申领的、适用于每台设备的配置参数。 某些类可能会由多个驱动所满足,因此每个供应商配置的实例仅适用于一个驱动。 这些配置参数被传递给驱动,但在分配申领时不考虑这些配置参数。 **DeviceClassConfiguration 在 DeviceClass 中使用。** - **config.opaque** (OpaqueDeviceConfiguration) opaque 提供特定于驱动的配置参数。 **OpaqueDeviceConfiguration 以驱动供应商所定义的格式提供驱动的配置参数。** - **config.opaque.driver** (string),必需 driver 用于确定需要将这些配置参数传递给哪个 kubelet 插件。 驱动开发者所提供的准入策略可以使用此字段来决定是否需要校验这些参数。 必须是一个 DNS 子域,并且应以驱动供应商拥有的 DNS 域结尾。 - **config.opaque.parameters** (RawExtension),必需 parameters 可以包含任意数据。处理校验和版本控制是驱动开发者的责任。 通常这包括自我识别和版本化管理(对 Kubernetes 而言即 "kind" + "apiVersion"),并在不同版本之间进行转换。 **RawExtension 用于以外部版本来保存扩展数据。** 要使用它,请生成一个字段,在外部、版本化结构中以 RawExtension 作为其类型,在内部结构中以 Object 作为其类型。 你还需要注册你的各个插件类型。 // 内部包: type MyAPIObject struct { runtime.TypeMeta `json:",inline"` MyPlugin runtime.Object `json:"myPlugin"` } type PluginA struct { AOption string `json:"aOption"` } // 外部包: type MyAPIObject struct { runtime.TypeMeta `json:",inline"` MyPlugin runtime.RawExtension `json:"myPlugin"` } type PluginA struct { AOption string `json:"aOption"` } // 在网络上,JSON 看起来像这样: { "kind":"MyAPIObject", "apiVersion":"v1", "myPlugin": { "kind":"PluginA", "aOption":"foo", }, } 那么会发生什么?解码首先使用 JSON 或 YAML 将序列化数据解组到你的外部 MyAPIObject 中。 这会导致原始 JSON 被存储下来,但不会被解包。下一步是复制(使用 pkg/conversion)到内部结构中。 runtime 包的 DefaultScheme 安装了转换函数,它将解析存储在 RawExtension 中的 JSON, 将其转换为正确的对象类型,并将其存储在 Object 中。 (TODO:如果对象是未知类型,将创建并存储一个 `runtime.Unknown` 对象。) - **selectors** ([]DeviceSelector) **原子:将在合并期间被替换** 每个选择算符必须由通过此类申领的设备所满足。 **DeviceSelector 必须设置一个字段。** - **selectors.cel** (CELDeviceSelector) cel 包含用于选择设备的 CEL 表达式。 **CELDeviceSelector 包含用于选择设备的 CEL 表达式。** - **selectors.cel.expression** (string),必需 expression 是一个 CEL 表达式,用于评估单个设备。 当被考虑的设备满足所需条件时,表达式的求值结果必须为 true;当不满足时,结果应为 false。 任何其他结果都是错误,会导致设备分配中止。 表达式的输入是一个名为 "device" 的对象,具有以下属性: - driver (string):定义此设备的驱动的名称。 - attributes (map[string]object):设备的属性,按前缀分组 (例如,device.attributes["dra.example.com"] 评估为一个对象,包含所有以 "dra.example.com" 为前缀的属性。) - capacity (map[string]object):设备的容量,按前缀分组。 示例:考虑一个驱动为 "dra.example.com" 的设备,它暴露两个名为 "model" 和 "ext.example.com/family" 的属性, 并且暴露一个名为 "modules" 的容量。此表达式的输入将具有以下字段: ``` device.driver device.attributes["dra.example.com"].model device.attributes["ext.example.com"].family device.capacity["dra.example.com"].modules ``` device.driver 字段可用于检查特定驱动,既可以作为高层次的前提条件(即你只想考虑来自此驱动的设备), 也可以作为考虑来自不同驱动的设备的多子句表达式的一部分。 attribute 中每个元素的值类型由设备定义,编写这些表达式的用户必须查阅其特定驱动的文档。 capacity 中元素的值类型为 Quantity。 如果在 device.attributes 或 device.capacity 中使用未知前缀进行查找, 将返回一个空映射。对未知字段的任何引用将导致评估错误和分配中止。 一个健壮的表达式应在引用属性之前检查其是否存在。 为了方便使用,cel.bind() 函数被启用,此函数可用于简化访问同一域的多个属性的表达式。例如: ``` cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) ``` - **suitableNodes** (NodeSelector) 当 Pod 使用还未分配的申领**且**该申领通过控制平面控制器分配时,如果调度器在尝试查找适合 Pod 的节点, 将仅考虑与选择算符匹配的节点。当申领不使用控制平面控制器进行分配时,此字段将被忽略。 设置此字段是可选的,如果不设置,则所有节点都是候选者。 这是一个 Alpha 字段,需要启用 DRAControlPlaneController 特性门控。 **节点选择算符表示针对一组节点执行一个或多个标签查询的结果的并集; 也就是说,它表示由节点选择算符条件表示的选择算符的逻辑或计算结果。** - **suitableNodes.nodeSelectorTerms** ([]NodeSelectorTerm),必需 **原子:将在合并期间被替换** 必需。节点选择算符条件的列表。这些条件会按逻辑或的关系来计算。 **Null 或空的节点选择算符条件不会与任何对象匹配。这些条件会按逻辑与的关系来计算。 TopologySelectorTerm 类别实现了 NodeSelectorTerm 的子集。** - **suitableNodes.nodeSelectorTerms.matchExpressions** ([]}}">NodeSelectorRequirement) **原子:将在合并期间被替换** 基于节点标签所设置的节点选择算符要求的列表。 - **suitableNodes.nodeSelectorTerms.matchFields** ([]}}">NodeSelectorRequirement) **原子:将在合并期间被替换** 基于节点字段所设置的节点选择算符要求的列表。 ## DeviceClassList {#DeviceClassList} DeviceClassList 是类的集合。
- **apiVersion**: resource.k8s.io/v1alpha3 - **kind**: DeviceClassList - **metadata** (}}">ListMeta) 标准的列表元数据。 - **items** ([]}}">DeviceClass),必需 items 是资源类的列表。 ## 操作 {#Operations}
### `get` 读取指定的 DeviceClass #### HTTP 请求 GET /apis/resource.k8s.io/v1alpha3/deviceclasses/{name} #### 参数 - **name**(**路径参数**):string,必需 DeviceClass 的名称。 - **pretty**(**查询参数**):string }}">pretty #### 响应 200 (}}">DeviceClass): OK 401: Unauthorized ### `list` 列举或监视 DeviceClass 类别的对象 #### HTTP 请求 GET /apis/resource.k8s.io/v1alpha3/deviceclasses #### 参数 - **allowWatchBookmarks** (**查询参数**): boolean }}">allowWatchBookmarks - **continue** (**查询参数**): string }}">continue - **fieldSelector** (**查询参数**): string }}">fieldSelector - **labelSelector** (**查询参数**): string }}">labelSelector - **limit** (**查询参数**): integer }}">limit - **pretty** (**查询参数**): string }}">pretty - **resourceVersion** (**查询参数**): string }}">resourceVersion - **resourceVersionMatch** (**查询参数**): string }}">resourceVersionMatch - **sendInitialEvents** (**查询参数**): boolean }}">sendInitialEvents - **timeoutSeconds** (**查询参数**): integer }}">timeoutSeconds - **watch** (**查询参数**): boolean }}">watch #### 响应 200 (}}">DeviceClassList): OK 401: Unauthorized ### `create` 创建 DeviceClass #### HTTP 请求 POST /apis/resource.k8s.io/v1alpha3/deviceclasses #### 参数 - **body**: }}">DeviceClass,必需 - **dryRun** (**查询参数**): string }}">dryRun - **fieldManager** (**查询参数**): string }}">fieldManager - **fieldValidation** (**查询参数**): string }}">fieldValidation - **pretty** (**查询参数**): string }}">pretty #### 响应 200 (}}">DeviceClass): OK 201 (}}">DeviceClass): Created 202 (}}">DeviceClass): Accepted 401: Unauthorized ### `update` 替换指定的 DeviceClass #### HTTP 请求 PUT /apis/resource.k8s.io/v1alpha3/deviceclasses/{name} #### 参数 - **name** (**路径参数**): string,必需 DeviceClass 的名称。 - **body**: }}">DeviceClass,必需 - **dryRun** (**查询参数**): string }}">dryRun - **fieldManager** (**查询参数**): string }}">fieldManager - **fieldValidation** (**查询参数**): string }}">fieldValidation - **pretty** (**查询参数**): string }}">pretty #### 响应 200 (}}">DeviceClass): OK 201 (}}">DeviceClass): Created 401: Unauthorized ### `patch` 部分更新指定的 DeviceClass #### HTTP 请求 PATCH /apis/resource.k8s.io/v1alpha3/deviceclasses/{name} #### 参数 - **name** (**路径参数**): string,必需 DeviceClass 的名称。 - **body**: }}">Patch,必需 - **dryRun** (**查询参数**): string }}">dryRun - **fieldManager** (**查询参数**): string }}">fieldManager - **fieldValidation** (**查询参数**): string }}">fieldValidation - **force** (**查询参数**): boolean }}">force - **pretty** (**查询参数**): string }}">pretty #### 响应 200 (}}">DeviceClass): OK 201 (}}">DeviceClass): Created 401: Unauthorized ### `delete` 删除 DeviceClass #### HTTP 请求 DELETE /apis/resource.k8s.io/v1alpha3/deviceclasses/{name} #### 参数 - **name** (**路径参数**): string,必需 DeviceClass 的名称。 - **body**: }}">DeleteOptions - **dryRun** (**查询参数**): string }}">dryRun - **gracePeriodSeconds** (**查询参数**): integer }}">gracePeriodSeconds - **pretty** (**查询参数**): string }}">pretty - **propagationPolicy** (**查询参数**): string }}">propagationPolicy #### 响应 200 (}}">DeviceClass): OK 202 (}}">DeviceClass): Accepted 401: Unauthorized ### `deletecollection` 删除 DeviceClass 的集合 #### HTTP 请求 DELETE /apis/resource.k8s.io/v1alpha3/deviceclasses #### 参数 - **body**: }}">DeleteOptions - **continue** (**查询参数**): string }}">continue - **dryRun** (**查询参数**): string }}">dryRun - **fieldSelector** (**查询参数**): string }}">fieldSelector - **gracePeriodSeconds** (**查询参数**): integer }}">gracePeriodSeconds - **labelSelector** (**查询参数**): string }}">labelSelector - **limit** (**查询参数**): integer }}">limit - **pretty** (**查询参数**): string }}">pretty - **propagationPolicy** (**查询参数**): string }}">propagationPolicy - **resourceVersion** (**查询参数**): string }}">resourceVersion - **resourceVersionMatch** (**查询参数**): string }}">resourceVersionMatch - **sendInitialEvents** (**查询参数**): boolean }}">sendInitialEvents - **timeoutSeconds** (**查询参数**): integer }}">timeoutSeconds #### 响应 200 (}}">Status): OK 401: Unauthorized