fix: add service for application controller statefulset (#29498)
Project: argoproj/argo-cd | Language: Go / YAML | Concepts: configuration-management | Difficulty: junior
Link: https://github.com/argoproj/argo-cd/pull/29499
The problem
The Argo CD Application Controller is deployed as a Kubernetes StatefulSet, which expects a headless Service to exist for stable network identities and peer discovery. However, the manifests were missing this Service, which could break networking for the StatefulSet and cause issues with pod communication or service discovery.
Why it's non-trivial
A naive fix might simply add a regular Service, but StatefulSets require a headless Service (clusterIP: None) with proper selectors to provide DNS for each pod. Omitting this or misconfiguring the Service could result in broken StatefulSet networking, non-unique pod hostnames, or failures in inter-pod communication.
The approach
1. Define the headless Service manifest
A new manifest is added to define the required Service. Notice the use of clusterIP: None (making it headless), and the selector matches the application-controller pods:
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.kubernetes.io/component: application-controller
+ app.kubernetes.io/name: argocd-application-controller
+ app.kubernetes.io/part-of: argocd
+ name: argocd-application-controller
+spec:
+ clusterIP: None
+ selector:
+ app.kubernetes.io/name: argocd-application-controller
This ensures the Service is headless and only targets the correct pods.
2. Include the Service in the Kustomization base
The new Service manifest is added to the list of resources in the Kustomize base for the application controller:
-resources:
-- ../application-controller-roles
-- argocd-application-controller-statefulset.yaml
+- argocd-application-controller-service.yaml
- argocd-metrics.yaml
- argocd-application-controller-network-policy.yaml
This makes sure any installation using the base will include the Service.
3. Regenerate all installation bundles to include the Service
All installation YAMLs (standard, core, HA, namespaced, with/without hydrator) are updated to include the new Service. Example snippet from one of the bundles:
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.kubernetes.io/component: application-controller
+ app.kubernetes.io/name: argocd-application-controller
+ app.kubernetes.io/part-of: argocd
+ name: argocd-application-controller
+spec:
+ clusterIP: None
+ selector:
+ app.kubernetes.io/name: argocd-application-controller
This ensures that every installation method now deploys the required Service.
4. Update test manifest count
A test is updated to expect one more manifest, reflecting the addition:
- const countOfManifests = 50
+ const countOfManifests = 51
This keeps the test suite in sync with the manifest changes.
From the review thread
No notable review discussion on this PR.
Takeaways
- Always match Kubernetes resource requirements to controller expectations. If a StatefulSet expects a headless Service, ensure it exists and is correctly configured.
- Update all deployment variants when changing shared infrastructure. When a base manifest changes, regenerate all installation bundles to keep them consistent.
- Keep automated tests in sync with configuration changes. If the number of manifests changes, update tests to reflect the new state to avoid false negatives.