|
| 1 | +--- |
| 2 | +title: 动态资源分配 |
| 3 | +content_type: concept |
| 4 | +weight: 65 |
| 5 | +--- |
| 6 | +<!-- |
| 7 | +reviewers: |
| 8 | +- klueska |
| 9 | +- pohly |
| 10 | +title: Dynamic Resource Allocation |
| 11 | +content_type: concept |
| 12 | +weight: 65 |
| 13 | +--> |
| 14 | + |
| 15 | +<!-- overview --> |
| 16 | + |
| 17 | +{{< feature-state for_k8s_version="v1.26" state="alpha" >}} |
| 18 | + |
| 19 | +<!-- |
| 20 | +Dynamic resource allocation is a new API for requesting and sharing resources |
| 21 | +between pods and containers inside a pod. It is a generalization of the |
| 22 | +persistent volumes API for generic resources. Third-party resource drivers are |
| 23 | +responsible for tracking and allocating resources. Different kinds of |
| 24 | +resources support arbitrary parameters for defining requirements and |
| 25 | +initialization. |
| 26 | +--> |
| 27 | +动态资源分配是一个用于在 Pod 之间和 Pod 内部容器之间请求和共享资源的新 API。 |
| 28 | +它是对为通用资源所提供的持久卷 API 的泛化。第三方资源驱动程序负责跟踪和分配资源。 |
| 29 | +不同类型的资源支持用任意参数进行定义和初始化。 |
| 30 | + |
| 31 | +## {{% heading "prerequisites" %}} |
| 32 | + |
| 33 | +<!-- |
| 34 | +Kubernetes v{{< skew currentVersion >}} includes cluster-level API support for |
| 35 | +dynamic resource allocation, but it [needs to be |
| 36 | +enabled](#enabling-dynamic-resource-allocation) explicitly. You also must |
| 37 | +install a resource driver for specific resources that are meant to be managed |
| 38 | +using this API. If you are not running Kubernetes v{{< skew currentVersion>}}, |
| 39 | +check the documentation for that version of Kubernetes. |
| 40 | +--> |
| 41 | +Kubernetes v{{< skew currentVersion >}} 包含用于动态资源分配的集群级 API 支持, |
| 42 | +但它需要被[显式启用](#enabling-dynamic-resource-allocation)。 |
| 43 | +你还必须为此 API 要管理的特定资源安装资源驱动程序。 |
| 44 | +如果你未运行 Kubernetes v{{< skew currentVersion>}}, |
| 45 | +请查看对应版本的 Kubernetes 文档。 |
| 46 | + |
| 47 | +<!-- body --> |
| 48 | + |
| 49 | +## API {#api} |
| 50 | +<!-- |
| 51 | +The new `resource.k8s.io/v1alpha1` {{< glossary_tooltip text="API group" |
| 52 | +term_id="api-group" >}} provides four new types: |
| 53 | +--> |
| 54 | +新的 `resource.k8s.io/v1alpha1` |
| 55 | +{{< glossary_tooltip text="API 组" term_id="api-group" >}}提供四种新类型: |
| 56 | + |
| 57 | +<!-- |
| 58 | +ResourceClass |
| 59 | +: Defines which resource driver handles a certain kind of |
| 60 | + resource and provides common parameters for it. ResourceClasses |
| 61 | + are created by a cluster administrator when installing a resource |
| 62 | + driver. |
| 63 | +
|
| 64 | +ResourceClaim |
| 65 | +: Defines a particular resource instances that is required by a |
| 66 | + workload. Created by a user (lifecycle managed manually, can be shared |
| 67 | + between different Pods) or for individual Pods by the control plane based on |
| 68 | + a ResourceClaimTemplate (automatic lifecycle, typically used by just one |
| 69 | + Pod). |
| 70 | +
|
| 71 | +ResourceClaimTemplate |
| 72 | +: Defines the spec and some meta data for creating |
| 73 | + ResourceClaims. Created by a user when deploying a workload. |
| 74 | +
|
| 75 | +PodScheduling |
| 76 | +: Used internally by the control plane and resource drivers |
| 77 | + to coordinate pod scheduling when ResourceClaims need to be allocated |
| 78 | + for a Pod. |
| 79 | +--> |
| 80 | +ResourceClass |
| 81 | +: 定义由哪个资源驱动程序处理某种资源,并为其提供通用参数。 |
| 82 | + 集群管理员在安装资源驱动程序时创建 ResourceClass。 |
| 83 | + |
| 84 | +ResourceClaim |
| 85 | +: 定义工作负载所需的特定资源实例。 |
| 86 | + 由用户创建(手动管理生命周期,可以在不同的 Pod 之间共享), |
| 87 | + 或者由控制平面基于 ResourceClaimTemplate 为特定 Pod 创建 |
| 88 | + (自动管理生命周期,通常仅由一个 Pod 使用)。 |
| 89 | + |
| 90 | +ResourceClaimTemplate |
| 91 | +: 定义用于创建 ResourceClaim 的 spec 和一些元数据。 |
| 92 | + 部署工作负载时由用户创建。 |
| 93 | + |
| 94 | +PodScheduling |
| 95 | +: 供控制平面和资源驱动程序内部使用, |
| 96 | + 在需要为 Pod 分配 ResourceClaim 时协调 Pod 调度。 |
| 97 | + |
| 98 | +<!-- |
| 99 | +Parameters for ResourceClass and ResourceClaim are stored in separate objects, |
| 100 | +typically using the type defined by a {{< glossary_tooltip |
| 101 | +term_id="CustomResourceDefinition" text="CRD" >}} that was created when |
| 102 | +installing a resource driver. |
| 103 | +--> |
| 104 | +ResourceClass 和 ResourceClaim 的参数存储在单独的对象中, |
| 105 | +通常使用安装资源驱动程序时创建的 {{< glossary_tooltip |
| 106 | +term_id="CustomResourceDefinition" text="CRD" >}} 所定义的类型。 |
| 107 | + |
| 108 | +<!-- |
| 109 | +The `core/v1` `PodSpec` defines ResourceClaims that are needed for a Pod in a new |
| 110 | +`resourceClaims` field. Entries in that list reference either a ResourceClaim |
| 111 | +or a ResourceClaimTemplate. When referencing a ResourceClaim, all Pods using |
| 112 | +this PodSpec (for example, inside a Deployment or StatefulSet) share the same |
| 113 | +ResourceClaim instance. When referencing a ResourceClaimTemplate, each Pod gets |
| 114 | +its own instance. |
| 115 | +--> |
| 116 | +`core/v1` 的 `PodSpec` 在新的 `resourceClaims` 字段中定义 Pod 所需的 ResourceClaim。 |
| 117 | +该列表中的条目引用 ResourceClaim 或 ResourceClaimTemplate。 |
| 118 | +当引用 ResourceClaim 时,使用此 PodSpec 的所有 Pod |
| 119 | +(例如 Deployment 或 StatefulSet 中的 Pod)共享相同的 ResourceClaim 实例。 |
| 120 | +引用 ResourceClaimTemplate 时,每个 Pod 都有自己的实例。 |
| 121 | + |
| 122 | +<!-- |
| 123 | +The `resources.claims` list for container resources defines whether a container gets |
| 124 | +access to these resource instances, which makes it possible to share resources |
| 125 | +between one or more containers. |
| 126 | +
|
| 127 | +Here is an example for a fictional resource driver. Two ResourceClaim objects |
| 128 | +will get created for this Pod and each container gets access to one of them. |
| 129 | +--> |
| 130 | +容器资源的 `resources.claims` 列表定义容器可以访问的资源实例, |
| 131 | +从而可以实现在一个或多个容器之间共享资源。 |
| 132 | + |
| 133 | +下面是一个虚构的资源驱动程序的示例。 |
| 134 | +该示例将为此 Pod 创建两个 ResourceClaim 对象,每个容器都可以访问其中一个。 |
| 135 | + |
| 136 | +```yaml |
| 137 | +apiVersion: resource.k8s.io/v1alpha1 |
| 138 | +kind: ResourceClass |
| 139 | +name: resource.example.com |
| 140 | +driverName: resource-driver.example.com |
| 141 | +--- |
| 142 | +apiVersion: cats.resource.example.com/v1 |
| 143 | +kind: ClaimParameters |
| 144 | +name: large-black-cat-claim-parameters |
| 145 | +spec: |
| 146 | + color: black |
| 147 | + size: large |
| 148 | +--- |
| 149 | +apiVersion: resource.k8s.io/v1alpha1 |
| 150 | +kind: ResourceClaimTemplate |
| 151 | +metadata: |
| 152 | + name: large-black-cat-claim-template |
| 153 | +spec: |
| 154 | + spec: |
| 155 | + resourceClassName: resource.example.com |
| 156 | + parametersRef: |
| 157 | + apiGroup: cats.resource.example.com |
| 158 | + kind: ClaimParameters |
| 159 | + name: large-black-cat-claim-parameters |
| 160 | +–-- |
| 161 | +apiVersion: v1 |
| 162 | +kind: Pod |
| 163 | +metadata: |
| 164 | + name: pod-with-cats |
| 165 | +spec: |
| 166 | + containers: |
| 167 | + - name: container0 |
| 168 | + image: ubuntu:20.04 |
| 169 | + command: ["sleep", "9999"] |
| 170 | + resources: |
| 171 | + claims: |
| 172 | + - name: cat-0 |
| 173 | + - name: container1 |
| 174 | + image: ubuntu:20.04 |
| 175 | + command: ["sleep", "9999"] |
| 176 | + resources: |
| 177 | + claims: |
| 178 | + - name: cat-1 |
| 179 | + resourceClaims: |
| 180 | + - name: cat-0 |
| 181 | + source: |
| 182 | + resourceClaimTemplateName: large-black-cat-claim-template |
| 183 | + - name: cat-1 |
| 184 | + source: |
| 185 | + resourceClaimTemplateName: large-black-cat-claim-template |
| 186 | +``` |
| 187 | +<!-- |
| 188 | +## Scheduling |
| 189 | +--> |
| 190 | +## 调度 {#scheduling} |
| 191 | +
|
| 192 | +<!-- |
| 193 | +In contrast to native resources (CPU, RAM) and extended resources (managed by a |
| 194 | +device plugin, advertised by kubelet), the scheduler has no knowledge of what |
| 195 | +dynamic resources are available in a cluster or how they could be split up to |
| 196 | +satisfy the requirements of a specific ResourceClaim. Resource drivers are |
| 197 | +responsible for that. They mark ResourceClaims as "allocated" once resources |
| 198 | +for it are reserved. This also then tells the scheduler where in the cluster a |
| 199 | +ResourceClaim is available. |
| 200 | +--> |
| 201 | +与原生资源(CPU、RAM)和扩展资源(由设备插件管理,并由 kubelet 公布)不同, |
| 202 | +调度器不知道集群中有哪些动态资源, |
| 203 | +也不知道如何将它们拆分以满足特定 ResourceClaim 的要求。 |
| 204 | +资源驱动程序负责这些任务。 |
| 205 | +资源驱动程序在为 ResourceClaim 保留资源后将其标记为“已分配(Allocated)”。 |
| 206 | +然后告诉调度器集群中可用的 ResourceClaim 的位置。 |
| 207 | +
|
| 208 | +<!-- |
| 209 | +ResourceClaims can get allocated as soon as they are created ("immediate |
| 210 | +allocation"), without considering which Pods will use them. The default is to |
| 211 | +delay allocation until a Pod gets scheduled which needs the ResourceClaim |
| 212 | +(i.e. "wait for first consumer"). |
| 213 | +--> |
| 214 | +ResourceClaim 可以在创建时就进行分配(“立即分配”),不用考虑哪些 Pod 将使用它。 |
| 215 | +默认情况下采用延迟分配,直到需要 ResourceClaim 的 Pod 被调度时 |
| 216 | +(即“等待第一个消费者”)再进行分配。 |
| 217 | +
|
| 218 | +<!-- |
| 219 | +In that mode, the scheduler checks all ResourceClaims needed by a Pod and |
| 220 | +creates a PodScheduling object where it informs the resource drivers |
| 221 | +responsible for those ResourceClaims about nodes that the scheduler considers |
| 222 | +suitable for the Pod. The resource drivers respond by excluding nodes that |
| 223 | +don't have enough of the driver's resources left. Once the scheduler has that |
| 224 | +information, it selects one node and stores that choice in the PodScheduling |
| 225 | +object. The resource drivers then allocate their ResourceClaims so that the |
| 226 | +resources will be available on that node. Once that is complete, the Pod |
| 227 | +gets scheduled. |
| 228 | +--> |
| 229 | +在这种模式下,调度器检查 Pod 所需的所有 ResourceClaim,并创建一个 PodScheduling 对象, |
| 230 | +通知负责这些 ResourceClaim 的资源驱动程序,告知它们调度器认为适合该 Pod 的节点。 |
| 231 | +资源驱动程序通过排除没有足够剩余资源的节点来响应调度器。 |
| 232 | +一旦调度器有了这些信息,它就会选择一个节点,并将该选择存储在 PodScheduling 对象中。 |
| 233 | +然后,资源驱动程序为分配其 ResourceClaim,以便资源可用于该节点。 |
| 234 | +完成后,Pod 就会被调度。 |
| 235 | +
|
| 236 | +<!-- |
| 237 | +As part of this process, ResourceClaims also get reserved for the |
| 238 | +Pod. Currently ResourceClaims can either be used exclusively by a single Pod or |
| 239 | +an unlimited number of Pods. |
| 240 | +--> |
| 241 | +作为此过程的一部分,ResourceClaim 会为 Pod 保留。 |
| 242 | +目前,ResourceClaim 可以由单个 Pod 独占使用或不限数量的多个 Pod 使用。 |
| 243 | +
|
| 244 | +<!-- |
| 245 | +One key feature is that Pods do not get scheduled to a node unless all of |
| 246 | +their resources are allocated and reserved. This avoids the scenario where a Pod |
| 247 | +gets scheduled onto one node and then cannot run there, which is bad because |
| 248 | +such a pending Pod also blocks all other resources like RAM or CPU that were |
| 249 | +set aside for it. |
| 250 | +--> |
| 251 | +除非 Pod 的所有资源都已分配和保留,否则 Pod 不会被调度到节点,这是一个重要特性。 |
| 252 | +这避免了 Pod 被调度到一个节点但无法在那里运行的情况, |
| 253 | +这种情况很糟糕,因为被挂起 Pod 也会阻塞为其保留的其他资源,如 RAM 或 CPU。 |
| 254 | +
|
| 255 | +<!-- |
| 256 | +## Limitations |
| 257 | +--> |
| 258 | +## 限制 {#limitations} |
| 259 | +
|
| 260 | +<!-- |
| 261 | +The scheduler plugin must be involved in scheduling Pods which use |
| 262 | +ResourceClaims. Bypassing the scheduler by setting the `nodeName` field leads |
| 263 | +to Pods that the kubelet refuses to start because the ResourceClaims are not |
| 264 | +reserved or not even allocated. It may be possible to [remove this |
| 265 | +limitation](https://github.com/kubernetes/kubernetes/issues/114005) in the |
| 266 | +future. |
| 267 | +--> |
| 268 | +调度器插件必须参与调度那些使用 ResourceClaim 的 Pod。 |
| 269 | +通过设置 `nodeName` 字段绕过调度器会导致 kubelet 拒绝启动 Pod, |
| 270 | +因为 ResourceClaim 没有被保留或甚至根本没有被分配。 |
| 271 | +未来可能[去除该限制](https://github.com/kubernetes/kubernetes/issues/114005)。 |
| 272 | + |
| 273 | +<!-- |
| 274 | +## Enabling dynamic resource allocation |
| 275 | +--> |
| 276 | +## 启用动态资源分配 {#enabling-dynamic-resource-allocation} |
| 277 | + |
| 278 | +<!-- |
| 279 | +Dynamic resource allocation is an *alpha feature* and only enabled when the |
| 280 | +`DynamicResourceAllocation` [feature |
| 281 | +gate](/docs/reference/command-line-tools-reference/feature-gates/) and the |
| 282 | +`resource.k8s.io/v1alpha1` {{< glossary_tooltip text="API group" |
| 283 | +term_id="api-group" >}} are enabled. For details on that, see the |
| 284 | +`--feature-gates` and `--runtime-config` [kube-apiserver |
| 285 | +parameters](/docs/reference/command-line-tools-reference/kube-apiserver/). |
| 286 | +kube-scheduler, kube-controller-manager and kubelet also need the feature gate. |
| 287 | +--> |
| 288 | +动态资源分配是一个 **alpha 特性**,只有在启用 `DynamicResourceAllocation` |
| 289 | +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/) |
| 290 | +和 `resource.k8s.io/v1alpha1` {{< glossary_tooltip text="API 组" |
| 291 | +term_id="api-group" >}} 时才启用。 |
| 292 | +有关详细信息,参阅 `--feature-gates` 和 `--runtime-config` |
| 293 | +[kube-apiserver 参数](/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/)。 |
| 294 | +kube-scheduler、kube-controller-manager 和 kubelet 也需要设置该特性门控。 |
| 295 | + |
| 296 | +<!-- |
| 297 | +A quick check whether a Kubernetes cluster supports the feature is to list |
| 298 | +ResourceClass objects with: |
| 299 | +--> |
| 300 | +快速检查 Kubernetes 集群是否支持该功能的方法是列出 ResourceClass 对象: |
| 301 | + |
| 302 | +```shell |
| 303 | +kubectl get resourceclasses |
| 304 | +``` |
| 305 | + |
| 306 | +<!-- |
| 307 | +If your cluster supports dynamic resource allocation, the response is either a |
| 308 | +list of ResourceClass objects or: |
| 309 | +--> |
| 310 | +如果你的集群支持动态资源分配,则响应是 ResourceClass 对象列表或: |
| 311 | +``` |
| 312 | +No resources found |
| 313 | +``` |
| 314 | +
|
| 315 | +<!-- |
| 316 | +If not supported, this error is printed instead: |
| 317 | +--> |
| 318 | +如果不支持,则会输出如下错误: |
| 319 | +``` |
| 320 | +error: the server doesn't have a resource type "resourceclasses" |
| 321 | +``` |
| 322 | +
|
| 323 | +<!-- |
| 324 | +The default configuration of kube-scheduler enables the "DynamicResources" |
| 325 | +plugin if and only if the feature gate is enabled. Custom configurations may |
| 326 | +have to be modified to include it. |
| 327 | +--> |
| 328 | +kube-scheduler 的默认配置仅在启用特性门控时才启用 "DynamicResources" 插件。 |
| 329 | +自定义配置可能需要被修改才能启用它。 |
| 330 | +
|
| 331 | +<!-- |
| 332 | +In addition to enabling the feature in the cluster, a resource driver also has to |
| 333 | +be installed. Please refer to the driver's documentation for details. |
| 334 | +--> |
| 335 | +除了在集群中启用该功能外,还必须安装资源驱动程序。 |
| 336 | +欲了解详细信息,请参阅驱动程序的文档。 |
| 337 | +
|
| 338 | +## {{% heading "whatsnext" %}} |
| 339 | +
|
| 340 | +<!-- |
| 341 | + - For more information on the design, see the |
| 342 | +[Dynamic Resource Allocation KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md). |
| 343 | +--> |
| 344 | +- 了解更多该设计的信息, |
| 345 | + 参阅[动态资源分配 KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/3063-dynamic-resource-allocation/README.md)。 |
0 commit comments