-
Notifications
You must be signed in to change notification settings - Fork 37
Open
Description
1. Quick Debug Information
- OS/Version(e.g. RHEL8.6, Ubuntu22.04):
- Kernel Version:
- Container Runtime Type/Version(e.g. Containerd, CRI-O, Docker):
- K8s Flavor/Version(e.g. K8s, OCP, Rancher, GKE, EKS): OpenShift AI 3.0
- GPU Operator Version:
- NIM Operator Version: https://github.com/nvidia/k8s-nim-operator/pkgs/container/k8s-nim-operator/639739974
- LLM NIM Versions:
- NeMo Service Versions:
2. Issue or feature description
Briefly explain the issue in terms of expected behavior and current behavior.
Create a NIMService without setting expose field.
Error:
Error "Invalid value: "object": no such key: expose evaluating rule: .spec.expose.ingress is deprecated, and will be removed in a future release. If .spec.expose.ingress is set, please do not set .spec.expose.router.ingress." for field "spec".
3. Steps to reproduce the issue
Detailed steps to reproduce the issue.
Create a NIMService without setting expose field.
For example:
apiVersion: apps.nvidia.com/v1alpha1
kind: NIMService
metadata:
name: meta-llama3-8b-instruct
spec:
image:
pullPolicy: IfNotPresent
pullSecrets:
- ngc-secret
repository: nvcr.io/nim/meta/llama-3.1-8b-instruct
tag: 1.15.4
storage:
nimCache:
name: llama-3-1-8b-instruct
profile: '10e5c5c7b0037e16bc74e9ec32942256bf73fda9902c2697b6cbd8fe94b8b47e'
replicas: 1
tolerations:
- effect: NoSchedule
key: g5-gpu
operator: Exists
authSecret: ngc-api-secret
4. Information to attach
Analysis from claude:
The issue is likely related to how Kubernetes handles struct zero values and CEL's has() function. Let me explain what's probably happening.
The Problem
Even when you don't set spec.expose in your YAML, Kubernetes may initialize the Expose struct with zero values (empty structs) rather than leaving it as nil. This is because in the type definition at line 121 in nimservice_types.go:
Expose Expose `json:"expose,omitempty"`
The Expose field is not a pointer - it's a value type. This means:
1. Even with omitempty, if any nested field gets a default value, the entire struct exists
2. Looking at line 117 in common_types.go, Service.Port has a default:
// +kubebuilder:default:=8000
Port *int32 `json:"port,omitempty"`
3. This default value causes spec.expose.service to exist, which causes spec.expose to exist
How CEL's has() Evaluates
In CEL:
- has(self.expose.ingress) returns true even for an empty struct (zero value)
- has(self.expose.router) returns true even for an empty struct
- has(self.expose.router.ingress) might also return true if router.ingress exists as an empty struct
The validation fails because the CEL expression checks if these fields exist (even as empty structs), not whether they have meaningful values.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working