From 4108f5493706f463cc2ceb823b66b5e6ac8fb1ca Mon Sep 17 00:00:00 2001 From: jbhalodia-slack Date: Fri, 26 Jul 2024 04:39:55 -0400 Subject: [PATCH] Add topologySpreadConstraints (#2091) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update README and documentation (#2047) * Update docs Signed-off-by: Yi Chen * Remove docs and update README Signed-off-by: Yi Chen * Add link to monthly community meeting Signed-off-by: Yi Chen --------- Signed-off-by: Yi Chen Signed-off-by: jbhalodia-slack * Add PodDisruptionBudget to chart (#2078) * Add PodDisruptionBudget to chart Signed-off-by: Carlos Sánchez Páez Signed-off-by: Carlos Sánchez Páez Signed-off-by: Carlos Sánchez Páez * PR comments Signed-off-by: Carlos Sánchez Páez --------- Signed-off-by: Carlos Sánchez Páez Signed-off-by: Carlos Sánchez Páez Signed-off-by: jbhalodia-slack * Set topologySpreadConstraints Signed-off-by: jbhalodia-slack * Update README and increase patch version Signed-off-by: jbhalodia-slack * Revert replicaCount change Signed-off-by: jbhalodia-slack * Update README after master merger Signed-off-by: jbhalodia-slack * Update README Signed-off-by: jbhalodia-slack --------- Signed-off-by: Yi Chen Signed-off-by: jbhalodia-slack Signed-off-by: Carlos Sánchez Páez Signed-off-by: Carlos Sánchez Páez Co-authored-by: Yi Chen Co-authored-by: Carlos Sánchez Páez --- charts/spark-operator-chart/Chart.yaml | 2 +- charts/spark-operator-chart/README.md | 3 +- .../templates/deployment.yaml | 10 ++++ .../tests/deployment_test.yaml | 51 +++++++++++++++++++ .../tests/poddisruptionbudget_test.yaml | 7 +-- charts/spark-operator-chart/values.yaml | 12 +++++ 6 files changed, 80 insertions(+), 5 deletions(-) diff --git a/charts/spark-operator-chart/Chart.yaml b/charts/spark-operator-chart/Chart.yaml index 8e78d3f4a..6068bba17 100644 --- a/charts/spark-operator-chart/Chart.yaml +++ b/charts/spark-operator-chart/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: spark-operator description: A Helm chart for Spark on Kubernetes operator -version: 1.4.5 +version: 1.4.6 appVersion: v1beta2-1.6.2-3.5.0 keywords: - spark diff --git a/charts/spark-operator-chart/README.md b/charts/spark-operator-chart/README.md index cab86da27..5f9a6a2ad 100644 --- a/charts/spark-operator-chart/README.md +++ b/charts/spark-operator-chart/README.md @@ -1,6 +1,6 @@ # spark-operator -![Version: 1.4.5](https://img.shields.io/badge/Version-1.4.5-informational?style=flat-square) ![AppVersion: v1beta2-1.6.2-3.5.0](https://img.shields.io/badge/AppVersion-v1beta2--1.6.2--3.5.0-informational?style=flat-square) +![Version: 1.4.6](https://img.shields.io/badge/Version-1.4.6-informational?style=flat-square) ![AppVersion: v1beta2-1.6.2-3.5.0](https://img.shields.io/badge/AppVersion-v1beta2--1.6.2--3.5.0-informational?style=flat-square) A Helm chart for Spark on Kubernetes operator @@ -132,6 +132,7 @@ See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall) for command docum | sidecars | list | `[]` | Sidecar containers | | sparkJobNamespaces | list | `[""]` | List of namespaces where to run spark jobs | | tolerations | list | `[]` | List of node taints to tolerate | +| topologySpreadConstraints | list | `[]` | Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. Ref: [Pod Topology Spread Constraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) Specify topologySpreadConstraints without the labelSelector field, the labelSelector field will be set to "spark-operator.selectorLabels" subtemplate in the deployment.yaml file. | | uiService.enable | bool | `true` | Enable UI service creation for Spark application | | volumeMounts | list | `[]` | | | volumes | list | `[]` | | diff --git a/charts/spark-operator-chart/templates/deployment.yaml b/charts/spark-operator-chart/templates/deployment.yaml index cf12fb2e8..396f8ae01 100644 --- a/charts/spark-operator-chart/templates/deployment.yaml +++ b/charts/spark-operator-chart/templates/deployment.yaml @@ -138,3 +138,13 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} + {{- if and .Values.topologySpreadConstraints (gt (int .Values.replicaCount) 1) }} + {{- $selectorLabels := include "spark-operator.selectorLabels" . | fromYaml -}} + {{- $labelSelectorDict := dict "labelSelector" ( dict "matchLabels" $selectorLabels ) }} + topologySpreadConstraints: + {{- range .Values.topologySpreadConstraints }} + - {{ mergeOverwrite . $labelSelectorDict | toYaml | nindent 8 | trim }} + {{- end }} + {{ else if and .Values.topologySpreadConstraints (eq (int .Values.replicaCount) 1) }} + {{ fail "replicaCount must be greater than 1 to enable topologySpreadConstraints."}} + {{- end }} diff --git a/charts/spark-operator-chart/tests/deployment_test.yaml b/charts/spark-operator-chart/tests/deployment_test.yaml index 5debda193..055d3b25f 100644 --- a/charts/spark-operator-chart/tests/deployment_test.yaml +++ b/charts/spark-operator-chart/tests/deployment_test.yaml @@ -299,3 +299,54 @@ tests: - key: key2 operator: Exists effect: NoSchedule + + - it: Should not contain topologySpreadConstraints if topologySpreadConstraints is not set + set: + topologySpreadConstraints: [] + asserts: + - notExists: + path: spec.template.spec.topologySpreadConstraints + + - it: Should add topologySpreadConstraints if topologySpreadConstraints is set and replicaCount is greater than 1 + set: + replicaCount: 2 + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + asserts: + - equal: + path: spec.template.spec.topologySpreadConstraints + value: + - labelSelector: + matchLabels: + app.kubernetes.io/instance: spark-operator + app.kubernetes.io/name: spark-operator + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + - labelSelector: + matchLabels: + app.kubernetes.io/instance: spark-operator + app.kubernetes.io/name: spark-operator + maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + + - it: Should fail if topologySpreadConstraints is set and replicaCount is not greater than 1 + set: + replicaCount: 1 + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + asserts: + - failedTemplate: + errorMessage: "replicaCount must be greater than 1 to enable topologySpreadConstraints." + \ No newline at end of file diff --git a/charts/spark-operator-chart/tests/poddisruptionbudget_test.yaml b/charts/spark-operator-chart/tests/poddisruptionbudget_test.yaml index 3f702fd10..56b9e4fe3 100644 --- a/charts/spark-operator-chart/tests/poddisruptionbudget_test.yaml +++ b/charts/spark-operator-chart/tests/poddisruptionbudget_test.yaml @@ -17,21 +17,22 @@ tests: - it: Should render spark operator podDisruptionBudget if podDisruptionBudget.enable is true set: + replicaCount: 2 podDisruptionBudget: enable: true - documentIndex: 0 asserts: - containsDocument: apiVersion: policy/v1 kind: PodDisruptionBudget - name: spark-operator-podDisruptionBudget + name: spark-operator-pdb - it: Should set minAvailable from values set: + replicaCount: 2 podDisruptionBudget: enable: true minAvailable: 3 asserts: - equal: - path: spec.template.minAvailable + path: spec.minAvailable value: 3 diff --git a/charts/spark-operator-chart/values.yaml b/charts/spark-operator-chart/values.yaml index 6eefe666b..bcb3a100a 100644 --- a/charts/spark-operator-chart/values.yaml +++ b/charts/spark-operator-chart/values.yaml @@ -143,6 +143,18 @@ podDisruptionBudget: # Require `replicaCount` to be greater than 1 minAvailable: 1 +# -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. +# Ref: [Pod Topology Spread Constraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) +# Specify topologySpreadConstraints without the labelSelector field, the labelSelector field will be set +# to "spark-operator.selectorLabels" subtemplate in the deployment.yaml file. +topologySpreadConstraints: [] +# - maxSkew: 1 +# topologyKey: topology.kubernetes.io/zone +# whenUnsatisfiable: ScheduleAnyway +# - maxSkew: 1 +# topologyKey: kubernetes.io/hostname +# whenUnsatisfiable: DoNotSchedule + # nodeSelector -- Node labels for pod assignment nodeSelector: {}