From af9e5246ad09a304ef68d11f1467185dbd12fe72 Mon Sep 17 00:00:00 2001 From: TheRealNoob Date: Fri, 14 Jun 2024 02:13:44 -0700 Subject: [PATCH] Chart: Make pod affinity templatable. (#11453) * [helm] template pod affinity * update README * Apply suggestions from code review Co-authored-by: Marco Ebert * revert Chart.yaml version bump * add unittests * add docs defaultBackend.affinity * add README section to values * fix README syntax * Apply suggestions from code review Co-authored-by: Marco Ebert * Update charts/ingress-nginx/values.yaml Co-authored-by: Marco Ebert * update formatting of unittests + add README examples * fix affinity labels on default-backend * Apply suggestions from code review Co-authored-by: Marco Ebert * remove double quotes on string --------- Co-authored-by: Marco Ebert --- charts/ingress-nginx/README.md | 2 +- .../templates/controller-daemonset.yaml | 2 +- .../templates/controller-deployment.yaml | 2 +- .../templates/default-backend-deployment.yaml | 2 +- .../tests/controller-daemonset_test.yaml | 43 +++++++++++++++ .../tests/controller-deployment_test.yaml | 42 +++++++++++++++ .../default-backend-deployment_test.yaml | 43 +++++++++++++++ charts/ingress-nginx/values.yaml | 52 +++++++++++++++++-- 8 files changed, 179 insertions(+), 9 deletions(-) diff --git a/charts/ingress-nginx/README.md b/charts/ingress-nginx/README.md index d73a501144..e35da750a3 100644 --- a/charts/ingress-nginx/README.md +++ b/charts/ingress-nginx/README.md @@ -485,7 +485,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu | controller.udp.configMapNamespace | string | `""` | Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) | | controller.updateStrategy | object | `{}` | The update strategy to apply to the Deployment or DaemonSet # | | controller.watchIngressWithoutClass | bool | `false` | Process Ingress objects without ingressClass annotation/ingressClassName field Overrides value for --watch-ingress-without-class flag of the controller binary Defaults to false | -| defaultBackend.affinity | object | `{}` | | +| defaultBackend.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity | | defaultBackend.autoscaling.annotations | object | `{}` | | | defaultBackend.autoscaling.enabled | bool | `false` | | | defaultBackend.autoscaling.maxReplicas | int | `2` | | diff --git a/charts/ingress-nginx/templates/controller-daemonset.yaml b/charts/ingress-nginx/templates/controller-daemonset.yaml index 718e20c521..509d7a4c4c 100644 --- a/charts/ingress-nginx/templates/controller-daemonset.yaml +++ b/charts/ingress-nginx/templates/controller-daemonset.yaml @@ -203,7 +203,7 @@ spec: tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} {{- end }} {{- if .Values.controller.affinity }} - affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + affinity: {{ tpl (toYaml .Values.controller.affinity) $ | nindent 8 }} {{- end }} {{- if .Values.controller.topologySpreadConstraints }} topologySpreadConstraints: {{ tpl (toYaml .Values.controller.topologySpreadConstraints) $ | nindent 8 }} diff --git a/charts/ingress-nginx/templates/controller-deployment.yaml b/charts/ingress-nginx/templates/controller-deployment.yaml index 879802779e..77ea0052fc 100644 --- a/charts/ingress-nginx/templates/controller-deployment.yaml +++ b/charts/ingress-nginx/templates/controller-deployment.yaml @@ -206,7 +206,7 @@ spec: tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} {{- end }} {{- if .Values.controller.affinity }} - affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + affinity: {{ tpl (toYaml .Values.controller.affinity) $ | nindent 8 }} {{- end }} {{- if .Values.controller.topologySpreadConstraints }} topologySpreadConstraints: {{ tpl (toYaml .Values.controller.topologySpreadConstraints) $ | nindent 8 }} diff --git a/charts/ingress-nginx/templates/default-backend-deployment.yaml b/charts/ingress-nginx/templates/default-backend-deployment.yaml index 6834dba072..c6ccdd5c92 100644 --- a/charts/ingress-nginx/templates/default-backend-deployment.yaml +++ b/charts/ingress-nginx/templates/default-backend-deployment.yaml @@ -107,7 +107,7 @@ spec: tolerations: {{ toYaml .Values.defaultBackend.tolerations | nindent 8 }} {{- end }} {{- if .Values.defaultBackend.affinity }} - affinity: {{ toYaml .Values.defaultBackend.affinity | nindent 8 }} + affinity: {{ tpl (toYaml .Values.defaultBackend.affinity) $ | nindent 8 }} {{- end }} {{- if .Values.defaultBackend.topologySpreadConstraints }} topologySpreadConstraints: {{ tpl (toYaml .Values.defaultBackend.topologySpreadConstraints) $ | nindent 8 }} diff --git a/charts/ingress-nginx/tests/controller-daemonset_test.yaml b/charts/ingress-nginx/tests/controller-daemonset_test.yaml index 29359fd9ef..6ee794af94 100644 --- a/charts/ingress-nginx/tests/controller-daemonset_test.yaml +++ b/charts/ingress-nginx/tests/controller-daemonset_test.yaml @@ -95,3 +95,46 @@ tests: topologyKey: kubernetes.io/hostname maxSkew: 1 whenUnsatisfiable: ScheduleAnyway + + - it: should create a DaemonSet with affinity if `controller.affinity` is set + set: + controller.kind: DaemonSet + controller.affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ include "ingress-nginx.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname + asserts: + - equal: + path: spec.template.spec.affinity + value: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - ingress-nginx + - key: app.kubernetes.io/instance + operator: In + values: + - RELEASE-NAME + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname diff --git a/charts/ingress-nginx/tests/controller-deployment_test.yaml b/charts/ingress-nginx/tests/controller-deployment_test.yaml index d0330db909..82b97a0f72 100644 --- a/charts/ingress-nginx/tests/controller-deployment_test.yaml +++ b/charts/ingress-nginx/tests/controller-deployment_test.yaml @@ -118,3 +118,45 @@ tests: topologyKey: kubernetes.io/hostname maxSkew: 1 whenUnsatisfiable: ScheduleAnyway + + - it: should create a Deployment with affinity if `controller.affinity` is set + set: + controller.affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ include "ingress-nginx.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname + asserts: + - equal: + path: spec.template.spec.affinity + value: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - ingress-nginx + - key: app.kubernetes.io/instance + operator: In + values: + - RELEASE-NAME + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname diff --git a/charts/ingress-nginx/tests/default-backend-deployment_test.yaml b/charts/ingress-nginx/tests/default-backend-deployment_test.yaml index e6fd0c5412..e237fe7e35 100644 --- a/charts/ingress-nginx/tests/default-backend-deployment_test.yaml +++ b/charts/ingress-nginx/tests/default-backend-deployment_test.yaml @@ -92,3 +92,46 @@ tests: topologyKey: kubernetes.io/hostname maxSkew: 1 whenUnsatisfiable: ScheduleAnyway + + - it: should create a Deployment with affinity if `defaultBackend.affinity` is set + set: + defaultBackend.enabled: true + defaultBackend.affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ include "ingress-nginx.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - default-backend + topologyKey: kubernetes.io/hostname + asserts: + - equal: + path: spec.template.spec.affinity + value: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - ingress-nginx + - key: app.kubernetes.io/instance + operator: In + values: + - RELEASE-NAME + - key: app.kubernetes.io/component + operator: In + values: + - default-backend + topologyKey: kubernetes.io/hostname diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index f09edbe745..c662cd2bb3 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -260,11 +260,11 @@ controller: # - key: app.kubernetes.io/name # operator: In # values: - # - ingress-nginx + # - '{{ include "ingress-nginx.name" . }}' # - key: app.kubernetes.io/instance # operator: In # values: - # - ingress-nginx + # - '{{ .Release.Name }}' # - key: app.kubernetes.io/component # operator: In # values: @@ -279,16 +279,16 @@ controller: # - key: app.kubernetes.io/name # operator: In # values: - # - ingress-nginx + # - '{{ include "ingress-nginx.name" . }}' # - key: app.kubernetes.io/instance # operator: In # values: - # - ingress-nginx + # - '{{ .Release.Name }}' # - key: app.kubernetes.io/component # operator: In # values: # - controller - # topologyKey: "kubernetes.io/hostname" + # topologyKey: kubernetes.io/hostname # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ @@ -1011,7 +1011,49 @@ defaultBackend: # value: "value" # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + # -- Affinity and anti-affinity rules for server scheduling to nodes + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity affinity: {} + # # An example of preferred pod anti-affinity, weight is in the range 1-100 + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 100 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - '{{ include "ingress-nginx.name" . }}' + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - '{{ .Release.Name }}' + # - key: app.kubernetes.io/component + # operator: In + # values: + # - default-backend + # topologyKey: kubernetes.io/hostname + + # # An example of required pod anti-affinity + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - '{{ include "ingress-nginx.name" . }}' + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - '{{ .Release.Name }}' + # - key: app.kubernetes.io/component + # operator: In + # values: + # - default-backend + # topologyKey: kubernetes.io/hostname + # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. # Ref.: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ topologySpreadConstraints: []