From 26e6c1ce634cb67fee9bcbf7dae18d91037f09c8 Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Thu, 2 Jul 2026 07:57:15 +0000 Subject: [PATCH 1/6] Unify node affinity/tolerations across all ArgoCD components The application controller was the only component pinned to a dedicated `glueops-platform-argocd-app-controller` node pool (with `glueops-platform` as fallback) plus an extra matching toleration. Every other component (server, applicationSet, repoServer, notifications, redis-ha) targets `glueops.dev/role: glueops-platform` and inherits the `glueops-platform` toleration from `global.tolerations`. Align the controller with the rest so all pods the chart deploys use the same node selector/affinity rules: it now requires `glueops-platform` and inherits `global.tolerations` like the other components. Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index 0c915a7..253129e 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -87,25 +87,7 @@ controller: - key: "glueops.dev/role" operator: In values: - - "glueops-platform-argocd-app-controller" - "glueops-platform" - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: "glueops.dev/role" - operator: In - values: - - "glueops-platform-argocd-app-controller" - tolerations: - - key: "glueops.dev/role" - operator: "Equal" - value: "glueops-platform-argocd-app-controller" - effect: "NoSchedule" - - key: "glueops.dev/role" - operator: "Equal" - value: "glueops-platform" - effect: "NoSchedule" metrics: enabled: true replicas: 1 From 01ced4016a3a35e1bf0df9918b2cd4389a5ed79c Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Thu, 2 Jul 2026 08:18:03 +0000 Subject: [PATCH 2/6] Pin redis-ha nodeSelector so its helm-test pods stay on-platform The redis-ha server and haproxy pods were already pinned via additionalAffinities, but the subchart's helm-test pods (redis-ha-configmap-test, redis-ha-service-test) rendered with an empty nodeSelector and no affinity, so they were not constrained to the glueops-platform nodes. Those test pods only honor `redis-ha.nodeSelector`, not `additionalAffinities`. Set `redis-ha.nodeSelector: glueops.dev/role=glueops-platform`. Verified with `helm template` (argo-cd 5.50.0): the test pods now carry the nodeSelector, and the server/haproxy pods gain a matching (redundant with their existing required nodeAffinity) nodeSelector. All pod-producing workloads now target glueops-platform. Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index 253129e..693545a 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -62,6 +62,11 @@ redis-ha: values: - "glueops-platform" enabled: true + # nodeSelector applies to the redis-ha server, haproxy, AND the chart's + # helm-test pods (which only honor nodeSelector, not additionalAffinities), + # keeping every redis-ha pod on the glueops-platform nodes. + nodeSelector: + glueops.dev/role: "glueops-platform" tolerations: - key: "glueops.dev/role" operator: "Equal" From fd8b877c7311eb62455c8bac3acb540bd6eeac0c Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Thu, 2 Jul 2026 08:42:09 +0000 Subject: [PATCH 3/6] Revert app-controller change; add repoServer nodeSelector Per review feedback, restore the application controller to its original configuration: it keeps its dedicated `glueops-platform-argocd-app-controller` node pool (preferred, with `glueops-platform` as fallback) and tolerations for both taints. The dedicated-pool setup is the preferred arrangement. Also add an explicit `repoServer.nodeSelector: glueops.dev/role=glueops-platform` alongside its existing required nodeAffinity, guaranteeing repo-server pods stay on the platform regardless of the podAntiAffinity spreading hints. Verified with `helm template` (argo-cd 5.50.0): every pod-producing workload targets glueops-platform; the app-controller again prefers its dedicated pool. Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index 693545a..7e68491 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -92,7 +92,25 @@ controller: - key: "glueops.dev/role" operator: In values: + - "glueops-platform-argocd-app-controller" - "glueops-platform" + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + preference: + matchExpressions: + - key: "glueops.dev/role" + operator: In + values: + - "glueops-platform-argocd-app-controller" + tolerations: + - key: "glueops.dev/role" + operator: "Equal" + value: "glueops-platform-argocd-app-controller" + effect: "NoSchedule" + - key: "glueops.dev/role" + operator: "Equal" + value: "glueops-platform" + effect: "NoSchedule" metrics: enabled: true replicas: 1 @@ -109,6 +127,8 @@ repoServer: pdb: enabled: true minAvailable: 2 + nodeSelector: + glueops.dev/role: "glueops-platform" affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: From 8448d2b1372a1a52568b2186fda4fe0555916417 Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Thu, 2 Jul 2026 08:44:20 +0000 Subject: [PATCH 4/6] Add explicit nodeSelector to server, applicationSet, notifications Extend the nodeSelector treatment (already on repoServer and redis-ha) to the remaining argo-cd components so every pod that can be pinned via nodeSelector is, in addition to its existing required nodeAffinity. The application controller intentionally keeps NO nodeSelector: a nodeSelector is a hard glueops-platform requirement that would exclude its dedicated glueops-platform-argocd-app-controller pool. It continues to rely on its nodeAffinity (dedicated pool preferred, glueops-platform fallback). Verified with `helm template` (argo-cd 5.50.0). Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index 7e68491..be37990 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -5,6 +5,8 @@ crds: notifications: metrics: enabled: true + nodeSelector: + glueops.dev/role: "glueops-platform" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -160,6 +162,8 @@ applicationSet: metrics: enabled: true replicas: 2 + nodeSelector: + glueops.dev/role: "glueops-platform" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -234,6 +238,9 @@ configs: # @ignored server: # @ignored + nodeSelector: + glueops.dev/role: "glueops-platform" + # @ignored affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: From 60813c78dec2ea89949778f56ccba57422b1d0b7 Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Thu, 2 Jul 2026 10:52:28 +0000 Subject: [PATCH 5/6] Pin redisSecretInit for forward-compat with argo-cd chart v8/v9 Rendered the current values against argo-cd chart 5.50.0 (pinned), 8.6.4, and 9.7.1. All existing per-component keys (nodeSelector on server, applicationSet, notifications, repoServer, redis-ha; controller affinity) render identically across all three majors -- no schema breakage. v8/v9 introduce a new `argocd-redis-secret-init` Job (a pre-install/ pre-upgrade helm hook, run by Argo CD as a PreSync hook) that inherits global.tolerations but has no node targeting, so it would schedule on any node. Set `redisSecretInit.nodeSelector` to keep it on the platform. Harmless no-op on 5.50.0 (no redisSecretInit component; no strict values schema in any of the three charts). Verified: 0 unpinned pod-producing workloads on 5.50.0, 8.6.4, and 9.7.1. Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index be37990..b23971a 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -41,6 +41,14 @@ redis: exporter: image: repository: "ghcr.repo.gpkg.io/oliver006/redis_exporter" +# redisSecretInit is a pre-install/pre-upgrade hook Job added in newer argo-cd +# chart majors (v8/v9). It inherits global.tolerations but no node targeting, +# so pin it explicitly to keep it on the glueops-platform nodes. (No-op on the +# currently pinned 5.50.0 chart, which has no redisSecretInit component.) +# @ignored +redisSecretInit: + nodeSelector: + glueops.dev/role: "glueops-platform" redis-ha: image: repository: "ecr.repo.gpkg.io/docker/library/redis" From 96b957f7366630b6c14690ded1a262f4a7f3d13c Mon Sep 17 00:00:00 2001 From: Venkata Mutyala Date: Fri, 3 Jul 2026 08:30:24 +0000 Subject: [PATCH 6/6] Consolidate node pinning into chart global.affinity (chart 9.x) Replace the per-component nodeSelector + nodeAffinity boilerplate on server, applicationSet, notifications, repoServer, and redisSecretInit with a single chart-level global.affinity preset (podAntiAffinity: soft, nodeAffinity: type=hard for glueops.dev/role=glueops-platform). global.tolerations already carried the glueops-platform toleration. How the chart merges (argo-cd.affinity helper, verified in templates/_common.tpl): components without their own affinity inherit global.affinity; components that set affinity override it entirely; nodeSelector/tolerations are `component | default global`. Left overriding global on purpose: - controller: keeps its affinity (dedicated glueops-platform-argocd-app-controller pool preferred + glueops-platform fallback) and two-taint tolerations. - redis-ha: subchart, not reachable by global; keeps nodeSelector + tolerations + additionalAffinities (also pins its helm-test pods). - gatekeeper: raw extraObjects manifest; keeps its own nodeSelector + tolerations. global.nodeSelector is intentionally NOT used: it would AND onto the controller and exclude its dedicated pool (nodeSelector can't express the OR the controller's nodeAffinity does), so pinning is via global.affinity.nodeAffinity instead. Verified with `helm template` on 9.3.7 (deployed) and 9.7.1: 11/11 pod-producing workloads pinned to glueops-platform, 0 unpinned, controller dedicated pool + both tolerations intact. Independently reviewed by a Helm expert (approved). Note: existing pods won't migrate (nodeAffinity is IgnoredDuringExecution) -- roll the workloads after sync. metrics.enabled stays per-component (no global.metrics exists). No redis metrics changes. Co-Authored-By: Claude Opus 4.8 (1M context) --- argocd.yaml.tpl | 84 ++++++++----------------------------------------- 1 file changed, 13 insertions(+), 71 deletions(-) diff --git a/argocd.yaml.tpl b/argocd.yaml.tpl index b23971a..e6c764f 100644 --- a/argocd.yaml.tpl +++ b/argocd.yaml.tpl @@ -5,17 +5,6 @@ crds: notifications: metrics: enabled: true - nodeSelector: - glueops.dev/role: "glueops-platform" - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: "glueops.dev/role" - operator: In - values: - - "glueops-platform" # @ignored global: @@ -28,6 +17,19 @@ global: operator: "Equal" value: "glueops-platform" effect: "NoSchedule" + # Pin every first-party argo-cd component to the glueops-platform nodes from one + # place: components without their own affinity inherit this preset; components that + # set their own affinity (e.g. controller) override it. The redis-ha subchart and the + # gatekeeper extraObject are not reached by global and keep their own settings. + affinity: + podAntiAffinity: soft + nodeAffinity: + type: hard + matchExpressions: + - key: "glueops.dev/role" + operator: In + values: + - "glueops-platform" logging: format: json @@ -41,14 +43,6 @@ redis: exporter: image: repository: "ghcr.repo.gpkg.io/oliver006/redis_exporter" -# redisSecretInit is a pre-install/pre-upgrade hook Job added in newer argo-cd -# chart majors (v8/v9). It inherits global.tolerations but no node targeting, -# so pin it explicitly to keep it on the glueops-platform nodes. (No-op on the -# currently pinned 5.50.0 chart, which has no redisSecretInit component.) -# @ignored -redisSecretInit: - nodeSelector: - glueops.dev/role: "glueops-platform" redis-ha: image: repository: "ecr.repo.gpkg.io/docker/library/redis" @@ -137,50 +131,11 @@ repoServer: pdb: enabled: true minAvailable: 2 - nodeSelector: - glueops.dev/role: "glueops-platform" - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchLabels: - app.kubernetes.io/name: argocd-repo-server - topologyKey: kubernetes.io/hostname - - weight: 50 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app.kubernetes.io/name - operator: In - values: - - argocd-application-controller - topologyKey: kubernetes.io/hostname - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: "glueops.dev/role" - operator: In - values: - - "glueops-platform" # @ignored applicationSet: metrics: enabled: true replicas: 2 - nodeSelector: - glueops.dev/role: "glueops-platform" - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: "glueops.dev/role" - operator: In - values: - - "glueops-platform" configs: params: server.insecure: true @@ -246,19 +201,6 @@ configs: # @ignored server: # @ignored - nodeSelector: - glueops.dev/role: "glueops-platform" - # @ignored - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: "glueops.dev/role" - operator: In - values: - - "glueops-platform" - # @ignored metrics: enabled: true # @ignored