From a8fdd0aaaf627bf524327785ff5292be5dee2eed Mon Sep 17 00:00:00 2001 From: Qinghui Zhuang Date: Wed, 21 Oct 2026 10:01:13 +0000 Subject: [PATCH] feat(modeldeployment): add nodeLabelSelector for InferenceSet GPU node selection Expose the new v1beta1 InferenceSet spec.template.resource.labelSelector (kaito-project/kaito#2444) as the `nodeLabelSelector` chart value. Empty omits the field, so existing renders are unchanged. The schema restricts it to matchLabels/matchExpressions. Also update the instanceType docs: it is now optional on BYO clusters and filters nodes by instance type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- charts/modeldeployment/README.md | 3 +- .../templates/inferenceset.yaml | 12 +++++-- charts/modeldeployment/values.schema.json | 31 ++++++++++++++++++- charts/modeldeployment/values.yaml | 9 +++++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/charts/modeldeployment/README.md b/charts/modeldeployment/README.md index fe04f07..97ab830 100644 --- a/charts/modeldeployment/README.md +++ b/charts/modeldeployment/README.md @@ -41,7 +41,8 @@ over plaintext gRPC and **no `DestinationRule` is required**. | `model` | required | `""` | Preset model name. Used only as `spec.template.inference.preset.name`. | | `config` | optional | `""` | Name of a ConfigMap in the deployment namespace containing custom inference arguments. Rendered as `spec.template.inference.config`. | | `modelAccessSecret` | optional | `""` | Name of a Secret containing Hugging Face model access credentials. Rendered as `spec.template.inference.preset.presetOptions.modelAccessSecret`. | -| `instanceType` | optional | `Standard_NV36ads_A10_v5` | VM instance type for the underlying nodes. Set `""` to omit `spec.template.resource.instanceType`, as required on BYO-node clusters (KAITO `nodeProvisioner=byo`). | +| `instanceType` | optional | `Standard_NV36ads_A10_v5` | VM instance type for the underlying nodes. Set `""` to omit `spec.template.resource.instanceType`. Required with node auto-provisioning; optional on BYO-node clusters (KAITO `nodeProvisioner=byo`), where it restricts GPU nodes to `node.kubernetes.io/instance-type=`. | +| `nodeLabelSelector` | optional | `{}` | GPU node [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements) (`matchLabels` / `matchExpressions`), rendered as `spec.template.resource.labelSelector`. Empty omits it: with node auto-provisioning it inherits `spec.labelSelector`; on BYO-node clusters GPU nodes are auto-selected. Requires a KAITO release with kaito-project/kaito#2444 (v0.13.0+); older CRDs silently drop the field. | | `replicas` | optional | _empty_ | InferenceSet replicas (`spec.replicas`). Empty leaves `spec.replicas` unset (CRD default `1`; with `enableScaling=true`, KEDA moves it into `[minReplicas, maxReplicas]`). When set with `enableScaling=true` it must lie within `[minReplicas, maxReplicas]` and is re-applied only when its value changes (see [Replica ownership](#replica-ownership)). | | `minReplicas` | required when `enableScaling=true` | _empty_ | Autoscaling lower bound, wired to `scaledobject.kaito.sh/min-replicas`. Ignored when `enableScaling=false`. `0` enables [scale to zero](#scale-to-zero). | | `enableScaling` | optional | `false` | Wired to `scaledobject.kaito.sh/auto-provision`. Gates `minReplicas`, `maxReplicas` and the entire `scaling` block. | diff --git a/charts/modeldeployment/templates/inferenceset.yaml b/charts/modeldeployment/templates/inferenceset.yaml index e657b29..53877c3 100644 --- a/charts/modeldeployment/templates/inferenceset.yaml +++ b/charts/modeldeployment/templates/inferenceset.yaml @@ -233,12 +233,20 @@ spec: {{- end }} {{- end }} {{- /* - Empty instanceType omits the field, which KAITO requires on BYO - (nodeProvisioner=byo) clusters where nodes are not auto-provisioned. + Empty instanceType / nodeLabelSelector omit their fields. On BYO + (nodeProvisioner=byo) clusters both are optional node filters and KAITO + auto-selects GPU nodes when both are empty; with node auto-provisioning an + omitted labelSelector inherits spec.labelSelector. */}} resource: + {{- if or .Values.instanceType .Values.nodeLabelSelector }} {{- with .Values.instanceType }} instanceType: {{ . | quote }} + {{- end }} + {{- with .Values.nodeLabelSelector }} + labelSelector: + {{- toYaml . | nindent 8 }} + {{- end }} {{- else }} {} {{- end }} inference: diff --git a/charts/modeldeployment/values.schema.json b/charts/modeldeployment/values.schema.json index 47b4e86..e701a2d 100644 --- a/charts/modeldeployment/values.schema.json +++ b/charts/modeldeployment/values.schema.json @@ -85,7 +85,36 @@ }, "instanceType": { "type": "string", - "description": "VM instance type used for the underlying GPU nodes. Empty omits spec.template.resource.instanceType, as required on BYO-node clusters (KAITO nodeProvisioner=byo)." + "description": "VM instance type used for the underlying GPU nodes. Empty omits spec.template.resource.instanceType. Required with node auto-provisioning; optional on BYO-node clusters (KAITO nodeProvisioner=byo), where it restricts GPU nodes to node.kubernetes.io/instance-type=." + }, + "nodeLabelSelector": { + "description": "LabelSelector for the GPU nodes, rendered as spec.template.resource.labelSelector. Empty omits it: with node auto-provisioning it then inherits spec.labelSelector; on BYO-node clusters GPU nodes are auto-selected. Requires KAITO v0.13.0+.", + "anyOf": [ + {"type": "null"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "matchLabels": { + "type": "object", + "additionalProperties": {"type": "string"} + }, + "matchExpressions": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["key", "operator"], + "properties": { + "key": {"type": "string", "minLength": 1}, + "operator": {"type": "string", "enum": ["In", "NotIn", "Exists", "DoesNotExist"]}, + "values": {"type": "array", "items": {"type": "string"}} + } + } + } + } + } + ] }, "replicas": { "anyOf": [ diff --git a/charts/modeldeployment/values.yaml b/charts/modeldeployment/values.yaml index b0009fe..c5b750b 100644 --- a/charts/modeldeployment/values.yaml +++ b/charts/modeldeployment/values.yaml @@ -16,9 +16,16 @@ config: "" # modelAccessSecret names the Secret holding the Hugging Face access credentials. modelAccessSecret: "" -# instanceType is the VM instance type of the GPU nodes; set "" on BYO-node clusters to omit it. +# instanceType is the VM instance type of the GPU nodes; "" omits it. Required with node auto-provisioning; +# optional on BYO-node clusters, where it restricts GPU nodes to node.kubernetes.io/instance-type=. instanceType: "Standard_NV36ads_A10_v5" +# nodeLabelSelector is a LabelSelector (matchLabels / matchExpressions) for the GPU nodes, rendered as +# spec.template.resource.labelSelector; empty omits it. With node auto-provisioning an empty value inherits the +# InferenceSet spec.labelSelector; on BYO-node clusters GPU nodes are auto-selected. Requires a KAITO release with +# kaito-project/kaito#2444 (v0.13.0+); older CRDs silently drop it. +nodeLabelSelector: {} + # replicas sets spec.replicas when not empty (otherwise the CRD default of 1); with enableScaling it must lie # within [minReplicas, maxReplicas] and is reapplied on upgrade only when its value changes. replicas: ""