Skip to content

Expose the node's zone label to Solr as availability_zone - #892

Open
janhoy wants to merge 6 commits into
apache:mainfrom
janhoy:issue-556-node-zone-sysprop
Open

janhoy wants to merge 6 commits into
apache:mainfrom
janhoy:issue-556-node-zone-sysprop

Conversation

@janhoy

@janhoy janhoy commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

🤖 AI assisted 🤖

Closes #556

Solr's AffinityPlacementFactory spreads replicas across availability zones using each node's availability_zone system property. Getting that value into a Solr pod used to mean a hand-written init container that queried the API server for node labels, which needs node-read RBAC. The gist in the issue is the workaround people have been copying.

Kubernetes solved this: the PodTopologyLabels admission plugin copies the node's topology.kubernetes.io/zone label onto the pod at binding time, alpha in 1.33 and beta, on by default, since 1.35. So the value is now reachable through the Downward API with no RBAC and no init container.

New opt-in SolrCloud field availabilityZoneFromNodeLabel, exposed as the Helm value solrOptions.availabilityZoneFromNodeLabel. When set, the operator adds a SOLR_AVAILABILITY_ZONE envVar from the pod label and appends -Davailability_zone=$(SOLR_AVAILABILITY_ZONE) to SOLR_OPTS.

It is opt-in rather than automatic for two reasons: enabling it changes the pod spec, which costs a rolling restart, and on a cluster without the feature the label is absent so the property would be empty. Empty is harmless, since Solr then treats all nodes as one zone, exactly as it does today when no node reports a zone.

Only the zone label is wired up. Region and hostname are also copied by the plugin, but Solr's placement plugins have no use for them today.

New SolrCloud option `availabilityZoneFromNodeLabel` sets the
`availability_zone` system property from the pod's
`topology.kubernetes.io/zone` label, which Kubernetes copies from the
node since the PodTopologyLabels feature (default since v1.35). Solr's
AffinityPlacementFactory uses that property to spread replicas across
zones, which previously needed a hand-written init container with
node-read RBAC.

Closes apache#556

This comment was marked as resolved.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@HoustonPutman

Copy link
Copy Markdown
Contributor

A side note, Solr should start using better SysVar names for this plugin, so that the EnvUtils code will auto convert envVars... Though we will want to support older versions, so this is great we can just remove allSolrOpts = append(allSolrOpts, "-Davailability_zone=$(SOLR_AVAILABILITY_ZONE)") in the future.

@HoustonPutman

Copy link
Copy Markdown
Contributor

I like this, but I'd like it even more if we could automatically detect if the setting is enabled in Kubernetes and just use it if it is, and don't if it isn't. Then users wouldn't have to enable it at all.

@janhoy

janhoy commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

I like this, but I'd like it even more if we could automatically detect if the setting is enabled in Kubernetes and just use it if it is, and don't if it isn't. Then users wouldn't have to enable it at all.

That shuold be possible I suppose, do some introspection somewhere and default to true if supported.

Related to this, I also thought about enabling affinity placement plugin as default, with disk warning set to 85% disk used (operator knows pvc size), see #894. But that can be a followup issue once each of the features are included.

@janhoy janhoy added this to the main (v1.0.0) milestone Nov 10, 2026
# Conflicts:
#	docs/modules/solr-cloud/pages/solr-cloud-crd.adoc
@HoustonPutman

Copy link
Copy Markdown
Contributor

That shuold be possible I suppose, do some introspection somewhere and default to true if supported.

So looking through and testing things, there is actually no issue by just turning it on always. It will give an empty string for non-enabled Kubernetes clusters. And solr will handle that gracefully.

I think we should just always use it, and remove the CRD option.

Related to this, I also thought about enabling affinity placement plugin as default, with disk warning set to 85% disk used (operator knows pvc size), see #894. But that can be a followup issue once each of the features are included.

I do like this. There may be a problem with the plugin not allowing multiple of the same replica on the same node, but we can adjust the integration tests to make sure we never get into that state.

Replace the opt-in availabilityZoneFromNodeLabel option with always
setting the availability_zone system property. A missing zone label
resolves to an empty value, which Solr treats like having no zones, so
the property is safe on every cluster, and v0.10.0 already restarts the
Solr pods on upgrade.
Set the spread_domain system property to the node each Solr pod runs
on. With spreadAcrossDomains enabled in the AffinityPlacementFactory,
Solr then puts replicas of a shard on different Kubernetes nodes within
a zone.
Put the two Kind workers in different zones, and check that each Solr
node reports its node as spread_domain and, on Kubernetes v1.35+ where
pods get their node's zone label, that zone as availability_zone.
@HoustonPutman

Copy link
Copy Markdown
Contributor

Ok, I added some commits, enabling it by default, and adding the Kubernetes node name as the spread_domain. I'll make a separate PR to have Solr be able to use EnvVars here instead of sysProps, so we can remove the solrOpts part.

Feel free to revert if you don't like it. We can also move this to 1.0 if you don't want a rolling restart included when upgrading to v0.10, though I haven't checked if that will already happen or not.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose k8s topology labels to Solr PODs

3 participants