Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/v1beta1/solrcloud_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ type SolrCloudSpec struct {
//
//+optional
AdditionalLibs []string `json:"additionalLibs,omitempty"`

// AvailabilityZoneFromNodeLabel exposes the "topology.kubernetes.io/zone" label of the Kubernetes node
// that each Solr pod runs on as the "availability_zone" system property, which Solr's
// AffinityPlacementFactory uses to spread replicas across availability zones.
//
// Requires Kubernetes v1.33+ with the PodTopologyLabels feature enabled, which is the default since v1.35.
// On clusters without it the system property is set to an empty value.
//
//+optional
AvailabilityZoneFromNodeLabel *bool `json:"availabilityZoneFromNodeLabel,omitempty"`
}

func (spec *SolrCloudSpec) withDefaults(logger logr.Logger) (changed bool) {
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions config/crd/bases/solr.apache.org_solrclouds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@ spec:
- enabled
type: object
type: object
availabilityZoneFromNodeLabel:
description: |-
AvailabilityZoneFromNodeLabel exposes the "topology.kubernetes.io/zone" label of the Kubernetes node
that each Solr pod runs on as the "availability_zone" system property, which Solr's
AffinityPlacementFactory uses to spread replicas across availability zones.

Requires Kubernetes v1.33+ with the PodTopologyLabels feature enabled, which is the default since v1.35.
On clusters without it the system property is set to an empty value.
type: boolean
backupRepositories:
description: Allows specification of multiple different "repositories"
for Solr to use when backing up data.
Expand Down
31 changes: 31 additions & 0 deletions controllers/solrcloud_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,37 @@ var _ = FDescribe("SolrCloud controller - General", func() {
})
})

FContext("Solr Cloud with availabilityZoneFromNodeLabel", func() {
BeforeEach(func() {
solrCloud.Spec = solrv1beta1.SolrCloudSpec{
ZookeeperRef: &solrv1beta1.ZookeeperRef{
ConnectionInfo: &solrv1beta1.ZookeeperConnectionInfo{
InternalConnectionString: "host:7271",
},
},
AvailabilityZoneFromNodeLabel: newBoolPtr(true),
}
})
FIt("has the correct resources", func(ctx context.Context) {
By("testing the Solr StatefulSet")
statefulSet := expectStatefulSet(ctx, solrCloud, solrCloud.StatefulSetName())

testPodEnvVariables(map[string]string{
"SOLR_OPTS": "-DhostPort=$(SOLR_NODE_PORT) -Davailability_zone=$(SOLR_AVAILABILITY_ZONE)",
}, statefulSet.Spec.Template.Spec.Containers[0].Env)

var zoneEnvVar *corev1.EnvVar
for _, envVar := range statefulSet.Spec.Template.Spec.Containers[0].Env {
if envVar.Name == "SOLR_AVAILABILITY_ZONE" {
zoneEnvVar = &envVar
break
}
}
Expect(zoneEnvVar).To(Not(BeNil()), "SOLR_AVAILABILITY_ZONE env var should be set")
Expect(zoneEnvVar.ValueFrom.FieldRef.FieldPath).To(Equal("metadata.labels['topology.kubernetes.io/zone']"), "Wrong fieldRef for the availability zone env var")
})
})

FContext("Solr Cloud with changing generated SolrXML", func() {
BeforeEach(func() {
solrCloud.Spec = solrv1beta1.SolrCloudSpec{
Expand Down
12 changes: 12 additions & 0 deletions controllers/util/solr_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,18 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
podAnnotations[SolrXmlMd5Annotation] = reconcileConfigInfo[SolrXmlMd5Annotation]
}

if solrCloud.Spec.AvailabilityZoneFromNodeLabel != nil && *solrCloud.Spec.AvailabilityZoneFromNodeLabel {
envVars = append(envVars, corev1.EnvVar{
Name: "SOLR_AVAILABILITY_ZONE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: fmt.Sprintf("metadata.labels['%s']", corev1.LabelTopologyZone),
Comment thread
janhoy marked this conversation as resolved.
Resolved
},
},
})
allSolrOpts = append(allSolrOpts, "-Davailability_zone=$(SOLR_AVAILABILITY_ZONE)")
}

if solrCloud.Spec.SolrOpts != "" {
allSolrOpts = append(allSolrOpts, solrCloud.Spec.SolrOpts)
}
Expand Down
15 changes: 15 additions & 0 deletions docs/modules/solr-cloud/pages/solr-cloud-crd.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ Use the **`SolrCloud.spec.solrModules`** property to add a list of module names,
However, users might want to include custom code that is not an official Solr Module.
In order to facilitate this, the **`SolrCloud.spec.additionalLibs`** property takes a list of paths to folders, containing jars to load in the classpath of the SolrCloud.

=== Availability Zone Awareness

Solr's https://solr.apache.org/guide/solr/latest/configuration-guide/replica-placement-plugins.html#affinityplacementfactory[AffinityPlacementFactory] spreads replicas across availability zones, using the `availability_zone` system property of each Solr node.

Set **`SolrCloud.spec.availabilityZoneFromNodeLabel`** to `true` to have the operator set that system property from the `topology.kubernetes.io/zone` label of the Kubernetes node each pod runs on.

[source,yaml]
----
spec:
availabilityZoneFromNodeLabel: true
----

This requires Kubernetes `v1.33`+ with the `PodTopologyLabels` feature enabled, which is the default since `v1.35`.
On clusters without it the system property is set to an empty value, and Solr places replicas as if all nodes were in one zone.

== Data Storage

The SolrCloud CRD gives the option for users to use either
Expand Down
5 changes: 5 additions & 0 deletions helm/solr-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ annotations:
# Allowed syntax is described at: https://artifacthub.io/docs/topics/annotations/helm/#example
# 'kind' accepts values: "added", "changed", "deprecated", "removed", "fixed" and "security"
artifacthub.io/changes: |
- kind: added
description: New SolrCloud option 'availabilityZoneFromNodeLabel', which exposes the Kubernetes node's topology.kubernetes.io/zone label to Solr as the availability_zone system property used by AffinityPlacementFactory
links:
- name: Github Issue
url: https://github.com/apache/solr-operator/issues/556
- kind: added
description: The operator can now resize (expand) persistent data PVCs, which requires new RBAC permissions for persistentvolumeclaims (update/patch) and storageclasses (get/list/watch)
links:
Expand Down
9 changes: 9 additions & 0 deletions helm/solr-operator/crds/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,15 @@ spec:
- enabled
type: object
type: object
availabilityZoneFromNodeLabel:
description: |-
AvailabilityZoneFromNodeLabel exposes the "topology.kubernetes.io/zone" label of the Kubernetes node
that each Solr pod runs on as the "availability_zone" system property, which Solr's
AffinityPlacementFactory uses to spread replicas across availability zones.

Requires Kubernetes v1.33+ with the PodTopologyLabels feature enabled, which is the default since v1.35.
On clusters without it the system property is set to an empty value.
type: boolean
backupRepositories:
description: Allows specification of multiple different "repositories"
for Solr to use when backing up data.
Expand Down
1 change: 1 addition & 0 deletions helm/solr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Descriptions on how to use these options can be found in the [SolrCloud document
| solrOptions.gcTune | string | `""` | GC Tuning parameters for Solr |
| solrOptions.solrModules | []string | | List of packaged Solr Modules to load when running Solr. Note: There is no need to specify solr modules necessary for other parts of the Spec (i.e. `backupRepositories[].gcs`), those will be added automatically. |
| solrOptions.additionalLibs | []string | | List of paths in the Solr Image to add to the classPath when running Solr. (There is no need to include paths for solrModules here if already listed in `solrModules`, those paths will be added automatically.) Note that this setting has no effect on solrcloud clusters that rely on a user-provided `solr.xml` file. |
| solrOptions.availabilityZoneFromNodeLabel | boolean | `false` | Expose the Kubernetes node's `topology.kubernetes.io/zone` label to Solr as the `availability_zone` system property, used by Solr's AffinityPlacementFactory. Requires Kubernetes v1.33+ with the PodTopologyLabels feature, which is the default since v1.35. |
| solrOptions.security.authenticationType | string | `""` | Type of authentication to use for Solr |
| solrOptions.security.basicAuthSecret | string | `""` | Name of Secret in the same namespace that stores the basicAuth information for the Solr user |
| solrOptions.security.probesRequireAuth | boolean | | Whether the probes for the SolrCloud pod require auth |
Expand Down
4 changes: 4 additions & 0 deletions helm/solr/templates/solrcloud.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ spec:
{{- toYaml .Values.solrOptions.additionalLibs | nindent 4 }}
{{- end }}

{{- if .Values.solrOptions.availabilityZoneFromNodeLabel }}
availabilityZoneFromNodeLabel: true
{{- end }}

{{- if .Values.backupRepositories }}
backupRepositories:
{{- toYaml .Values.backupRepositories | nindent 4 }}
Expand Down
5 changes: 5 additions & 0 deletions helm/solr/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ solrOptions:
solrModules: []
additionalLibs: []

# Expose the Kubernetes node's "topology.kubernetes.io/zone" label to Solr as the
# "availability_zone" system property, for use by Solr's AffinityPlacementFactory.
# Requires Kubernetes v1.33+ with the PodTopologyLabels feature, the default since v1.35.
availabilityZoneFromNodeLabel: false

# Enable authentication for the Solr Cloud
# More information can be found at:
# https://solr.apache.org/guide/operator/latest/solr-cloud/authentication-and-authorization.html
Expand Down
Loading