Repository navigation
Feast operator always deploys an online store, regardless of CR configuration #6586
Description
Expected Behavior
The Feast operator should deploy only the services declared in a FeatureStore CR. It should be possible to deploy a standalone registry or a standalone offline store, with no online store, by simply not specifying spec.services.onlineStore. This mirrors how registry and offlineStore already behave and is required by the documented federated / shared registry pattern.
Current Behavior
The operator always deploys an online store service (including a serving pod), even when the CR does not declare spec.services.onlineStore. Root cause is in ApplyDefaultsToStatus (internal/controller/services/util.go):
// default to onlineStore service deployment
if services.OnlineStore == nil {
services.OnlineStore = &feastdevv1.OnlineStore{}
}
// ...
if services.OnlineStore.Server == nil {
services.OnlineStore.Server = &feastdevv1.ServerConfigs{} // forces a serving pod
}Unlike registry (if services.Registry != nil) and offlineStore (if services.OfflineStore != nil), which are only defaulted when declared, and whose .Server is only defaulted when already present, the onlineStore block runs unconditionally and creates Server from nil.
Downstream:
isOnlineStore()is always true →reconcileServices()always deploys the online store, andisOnlineServer()is always true. There's no opt-out, theOnlineStoreCRD type has nodisabledfield. (This also makes the "at least one local server must be configured" guard inDeploy()unreachable.)- The scaling admission validation is asymmetric (api/v1/featurestore_types.go): the offline rule allows the store to be absent (
!has(self.services.offlineStore) || ...), but the online rule requires it to exist and be DB-backed. So scaling a registry-only/offline-only store fails admission withScaling requires DB-backed persistence for the online store. Configure services.onlineStore.persistence.store when using replicas > 1 or autoscaling., forcing DB persistence for an online store the user never asked for.
Steps to reproduce
- Apply a CR declaring only a registry (or only an offline store), with no
spec.services.onlineStore. kubectl get deploy -l feast.dev/name=<name>→ an online/feature-server container is deployed alongside the registry (expected: registry only).- Add
spec.replicas: 2(orservices.scaling.autoscaling) to that registry-only CR → rejected at admission with the online-store DB-persistence error, despite no online store being declared.
Specifications
- Version: 0.64.0
- Platform: Kubernetes
- Subsystem: feast-operator — internal/controller/services
Possible Solution
- Guard the online-store block in
ApplyDefaultsToStatuswith ifservices.OnlineStore != nil { ... }(and only default Server when already present), making it symmetric with registry/offline. Preferable to adding a new opt-out API field. - Add an "online store absent" escape hatch to the online CEL rule (
!has(self.services.onlineStore) || (...)), matching the offline rule. - Keep
noLocalCoreServerConfigured()enforcing that at least one core server is deployed.
Happy to open a PR! 😄
Activity
test(operator): declare online store explicitly in tests that relied …
fix(operator): add spec.services.onlineStore.disabled to opt out of t…
fix(operator): add spec.services.onlineStore.disabled to opt out of t…
fix(operator): add spec.services.onlineStore.disabled to opt out of t…
fix(operator): add spec.services.onlineStore.disabled to opt out of t…
fix(operator): add spec.services.onlineStore.disabled to opt out of t…
chore(release): release 0.66.0
chore(release): release 0.66.0