diff --git a/helm/templates/webhook-deploy.yaml b/helm/templates/webhook-deploy.yaml index 56a110a4b..6ce5c2dbc 100644 --- a/helm/templates/webhook-deploy.yaml +++ b/helm/templates/webhook-deploy.yaml @@ -103,23 +103,7 @@ spec: (.Values.defaults.securityContext | default (dict)) (.Values.components.webhookServer.securityContext | default (dict)) ) | nindent 6 }} - {{ $podAntiAffinity := dict - "podAntiAffinity" (dict - "preferredDuringSchedulingIgnoredDuringExecution" (list - (dict - "weight" 100 - "podAffinityTerm" (dict - "labelSelector" (dict - "matchLabels" (dict "app.kubernetes.io/name" "webhook-server") - ) - "topologyKey" "kubernetes.io/hostname" - ) - ) - ) - ) - }} - {{- $userAffinity := deepCopy .Values.insightsController.server.affinity }} - {{- include "cloudzero-agent.generateAffinity" (dict "default" .Values.defaults.affinity "affinity" (merge $userAffinity $podAntiAffinity)) | nindent 6 }} + {{- include "cloudzero-agent.generateAffinity" (dict "default" .Values.defaults.affinity "affinity" .Values.insightsController.server.affinity) | nindent 6 }} {{- include "cloudzero-agent.generateDNSInfo" (dict "defaults" .Values.defaults.dns) | nindent 6 }} {{- include "cloudzero-agent.generatePriorityClassName" .Values.defaults.priorityClassName | nindent 6 }} {{- include "cloudzero-agent.generateNodeSelector" (dict "default" .Values.defaults.nodeSelector "nodeSelector" .Values.insightsController.server.nodeSelector) | nindent 6 }} diff --git a/helm/tests/server_aggregator_default_antiaffinity_test.yaml b/helm/tests/server_aggregator_default_antiaffinity_test.yaml new file mode 100644 index 000000000..6c3a83077 --- /dev/null +++ b/helm/tests/server_aggregator_default_antiaffinity_test.yaml @@ -0,0 +1,81 @@ +# Regression guard for the default pod anti-affinity now declared directly in +# values.yaml (server.affinity, aggregator.affinity, and +# insightsController.server.affinity) rather than hardcoded in the templates. +# +# Companion to webhook_antiaffinity_selector_test.yaml, which covers the same +# behavior for the webhook server. These assert that, with no user overrides, +# the server and aggregator Deployments render the same soft (preferred), +# weight-100, same-hostname anti-affinity rule scoped to their own +# app.kubernetes.io/name label - and that a user can still fully replace the +# default by overriding affinity. +suite: test default server/aggregator pod anti-affinity +templates: + - templates/agent-deploy.yaml + - templates/aggregator-deploy.yaml +tests: + - it: server should default to a preferred anti-affinity selecting its own pods + template: templates/agent-deploy.yaml + set: + components.agent.mode: clustered + asserts: + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.labelSelector.matchLabels + value: + app.kubernetes.io/name: server + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight + value: 100 + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey + value: kubernetes.io/hostname + + - it: aggregator should default to a preferred anti-affinity selecting its own pods + template: templates/aggregator-deploy.yaml + asserts: + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.labelSelector.matchLabels + value: + app.kubernetes.io/name: aggregator + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight + value: 100 + - equal: + path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey + value: kubernetes.io/hostname + + - it: users can fully replace the server's default anti-affinity + template: templates/agent-deploy.yaml + set: + components.agent.mode: clustered + server.affinity: + podAntiAffinity: null + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: srv-only-key + operator: Exists + asserts: + - notExists: + path: spec.template.spec.affinity.podAntiAffinity + - equal: + path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].key + value: srv-only-key + + - it: users can fully replace the aggregator's default anti-affinity + template: templates/aggregator-deploy.yaml + set: + aggregator.affinity: + podAntiAffinity: null + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: agg-only-key + operator: Exists + asserts: + - notExists: + path: spec.template.spec.affinity.podAntiAffinity + - equal: + path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].key + value: agg-only-key diff --git a/helm/values.yaml b/helm/values.yaml index 8e589a9b8..10020a222 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -1283,11 +1283,25 @@ server: # --Limit the size to 8Gi to lower impact on the cluster, and to provide a reasonable backup for the WAL emptyDir: sizeLimit: 8Gi - # Affinity rules + # Affinity rules for the server pods. + # + # Defaults to a preferred (soft) anti-affinity that spreads server pods + # across different nodes. Override any of these fields to customize the + # behavior, or set podAntiAffinity to null (or affinity to null) to + # remove the default entirely. Note: setting affinity to {} will NOT + # remove it, since Helm re-merges chart defaults into empty maps. # # See the Kubernetes documentation for details: # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - affinity: {} + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: server + topologyKey: kubernetes.io/hostname # Tolerations configuration for the aggregator pods. # # See the Kubernetes documentation for details: @@ -1508,9 +1522,24 @@ insightsController: tolerations: [] # Affinity rules for the webhook server pods. # + # Defaults to a preferred (soft) anti-affinity that spreads webhook + # server pods across different nodes. Override any of these fields to + # customize the behavior, or set podAntiAffinity to null (or affinity + # to null) to remove the default entirely. Note: setting affinity to + # {} will NOT remove it, since Helm re-merges chart defaults into + # empty maps. + # # See the Kubernetes documentation for details: # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - affinity: {} + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: webhook-server + topologyKey: kubernetes.io/hostname # Annotations to add to the webhook server Deployment. deploymentAnnotations: {} # Annotations to add to the webhook server pods. @@ -1806,9 +1835,24 @@ aggregator: tolerations: [] # Affinity rules for the aggregator pods. # + # Defaults to a preferred (soft) anti-affinity that spreads aggregator + # pods across different nodes. Override any of these fields to + # customize the behavior, or set podAntiAffinity to null (or affinity + # to null) to remove the default entirely. Note: setting affinity to + # {} will NOT remove it, since Helm re-merges chart defaults into + # empty maps. + # # See the Kubernetes documentation for details: # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity - affinity: {} + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: aggregator + topologyKey: kubernetes.io/hostname # -- Deprecated. Override the name of the chart. Used in resource naming. nameOverride: