Consolidate ArgoCD node pinning into chart global.affinity#55
Merged
Conversation
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Pin every ArgoCD pod to the
glueops.dev/role: glueops-platformnodes using the chart'sglobal.affinitypreset instead of repeating anodeSelector+nodeAffinityblock on each component. Targets the deployed chart 9.x (verified on 9.3.7 and 9.7.1). Net −36 lines.Change (single file:
argocd.yaml.tpl)global: addglobal.tolerationsalready carried theglueops-platformtoleration.)nodeSelector+affinityfromserver,applicationSet,notifications,repoServer, and deleted theredisSecretInitblock — they now inheritglobal.Left overriding global on purpose
affinity(dedicatedglueops-platform-argocd-app-controllerpool preferred +glueops-platformfallback) and two-tainttolerations.global; keepsnodeSelector+tolerations+additionalAffinities(also pins its helm-test pods).extraObjectsmanifest; keeps its ownnodeSelector+tolerations.Why not
global.nodeSelectorIt would AND onto the controller (whose
nodeSelectoris empty) and exclude its dedicated pool — anodeSelectorcan't express the OR the controller'snodeAffinitydoes. So pinning is viaglobal.affinity.nodeAffinity.Verification (
helm template)11/11 pod-producing workloads pinned, 0 unpinned on both 9.3.7 (deployed) and 9.7.1; controller keeps
req=[app-controller, glueops-platform],pref=[app-controller], both tolerations. Independently reviewed by a Helm expert (approved).Behavior notes
server/applicationSet/notificationsgain a soft own-pod host-spread (from the global preset) — preferred-only, good for HA.repoServerloses the mootweight:50"spread off app-controller" term (controller lives on its own pool); own-pod spread preserved via the global soft preset.requiredDuringSchedulingIgnoredDuringExecutionis schedule-time only. After merge + Argo sync,kubectl -n glueops-core rollout restartthe affected workloads so they reschedule. Ensure theglueops-platformpool has ≥3 nodes (redis-ha's required host anti-affinity).metrics.enabledstays per-component (there is noglobal.metrics). No redis metrics changes.Follow-up (separate, not in this PR)
README.mdstill documents installing chart5.50.0while the cluster runs9.3.7+— worth a doc update.🤖 Generated with Claude Code