argo-cd icon indicating copy to clipboard operation
argo-cd copied to clipboard

Server Side Apply is inconsistently applied

Open rajatvig opened this issue 8 months ago • 3 comments

Checklist:

  • [X] I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
  • [X] I've included steps to reproduce the bug.
  • [X] I've pasted the output of argocd version.

Describe the bug

When multiple field managers are active in a SSA, and ArgoCD is brought in after using SSA, it does not take ownership of fields the current manifest does not have leading to inconsistencies with the resource manifest as expected and as live.

This is even more so awkward as the live manifest and desired manifest are clearly different on inspection but there is no diff shown which leads to this being ignored entirely.

This is related to https://github.com/kubernetes/kubernetes/issues/131476 where in if multiple field managers are active, it leads to inconsistent resource.

To Reproduce

  1. Apply a deployment resource with affinities using SSA over CLI.
  2. Apply the same deployment with a different field manager using SSA without affinities.

The affinities do not change. Then null the managedFields and apply the same resource without affinities and it does not change.

Expected behavior

The affinities should change.

Version

2.14.9

rajatvig avatar Apr 25 '25 14:04 rajatvig

Can you try with v3 RC, please? There's been some rework of the server side diff and how the field managers are handled.

andrii-korotkov avatar Apr 27 '25 00:04 andrii-korotkov

kubernetes/kubernetes#124191 could help, if merged. Argo could then leverage the overwrite flag to become the only fieldmanager in town.

blakepettersson avatar Apr 30 '25 15:04 blakepettersson

@rajatvig @blakepettersson From my understanding this can be fixed by allowing argocd-controller to take ownership of the field you want to remove by re-declaring it with Argo CD’s field manager with --force-conflicts and changing the field values or setting them to null, then removing it from the manifest in a subsequent apply.

  1. Apply a deployment with a field manager
kubectl apply --server-side --field-manager=kubectl -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/e2e-az-name
                    operator: In
                    values:
                      - e2e-az1
                      - e2e-az2
      containers:
        - name: myapp
          image: nginx
EOF
  1. Apply the same manifest with argocd-controller, but change some values in affinity so we can introduce a conflict:
kubectl apply --server-side --force-conflicts --field-manager=argocd-controller -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/e2e-az-name-delete
                    operator: In
                    values:
                      - e2e-az1-delete
                      - e2e-az2-delete
      containers:
        - name: myapp
          image: nginx
EOF

At this point argocd-controller should own the affinity field 3. Remove the affinities from the deployment and do another kubectl apply --server-side

kubectl apply --server-side --field-manager=argocd-controller --force-conflicts -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: nginx
EOF
  1. Now the affinity field will be removed — because Argo CD owns it and it is missing from the manifest.

Its annoying to do but worked for me and i agree that it would be nice to have an --overwrite flag instead

pjiang-dev avatar Jun 02 '25 04:06 pjiang-dev

This may be solved with #23337

blakepettersson avatar Jun 12 '25 14:06 blakepettersson