argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
17.73k stars 5.4k forks source link

Application synchronization problem(Synchronized twice with different) #20163

Open Hargeek opened 3 weeks ago

Hargeek commented 3 weeks ago

**Checklist:

I use the method provided by "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" to synchronize the application.

func (acc *argoCDClient) SyncApplication(applicationName, argoCDInstanceName string) error {
    applicationSyncMutex.Lock()
    defer applicationSyncMutex.Unlock()

    startTime := time.Now()
    logger.Info(fmt.Sprintf("service: cd sync publish hook, sync instance: %s, application: %s start", argoCDInstanceName, applicationName))

    syncOptions := &application.SyncOptions{
        Items: []string{"ApplyOutOfSyncOnly", "Refresh=true", "RespectIgnoreDifferences=true"},
    }

    if _, err := acc.ApplicationClient.Sync(context.Background(), &application.ApplicationSyncRequest{
        Name: &applicationName,
        SyncOptions: syncOptions,
        Strategy: &argoappv1.SyncStrategy{
            Hook: &argoappv1.SyncStrategyHook{
                SyncStrategyApply: argoappv1.SyncStrategyApply{
                    Force: true,
                },
            },
            //Apply: &argoappv1.SyncStrategyApply{
            //  Force: true,
            //},
        },
    }); err != nil {
        return err
    }

    logger.Info(fmt.Sprintf("service: cd sync publish hook, sync instance: %s, application: %s finished, took %f seconds", argoCDInstanceName, applicationName, time.Since(startTime).Seconds()))

    return nil
}

Now I find that sometimes two records are generated almost at the same time. The record with the larger the id is the old version, which leads to the invalidity of the synchronization call. This situation is not inevitable. Sometimes it will happen.

115  2024-09-30 11:14:05 +0800 CST  cicd (4ddbed9)
116  2024-09-30 14:57:03 +0800 CST  cicd (5a06a9e)
117  2024-09-30 14:57:03 +0800 CST  cicd (74ed2d8)
118  2024-09-30 14:58:49 +0800 CST  cicd (5a06a9e)

We can only wait for the next synchronization, so that I can't realize the purpose of real-time synchronization after the git repository is modified. Please help me see what the reason is.

I tried version 2.4.3 and version 2.11.4, both are like this

I used the git generator to configure my app. The relevant definitions are as follows

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: golang-gin-demo
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: git@devops.azure.com:22/MyCompany/project1/_git/argocd-apps
        revision: HEAD
        files:
          - path: "cluster-config/**/config.yaml"
  template:
    metadata:
      name: 'golang-gin-demo-{{ cluster.env }}'
      finalizers:
        - resources-finalizer.argocd.argoproj.io
    spec:
      project: '{{ cluster.name }}'
      source:
        repoURL: '{{ source.repoURL }}'
        targetRevision: '{{ source.targetRevision }}'
        path: 'app-overlays/golang-gin-demo/{{ cluster.env }}'
      destination:
        server: '{{ cluster.url }}'
        namespace: '{{ cluster.namespace }}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
          allowEmpty: false
        syncOptions:
        - Validate=false
        - CreateNamespace=true
        - RespectIgnoreDifferences=true
        retry:
          limit: 5
          backoff:
            duration: 5s
            factor: 2
            maxDuration: 3m
      ignoreDifferences:
      - group: "apps"
        kind: "Deployment"
        jsonPointers:
        - /spec/replicas

Version

~ argocd version
argocd: v2.11.4+e1284e1
  BuildDate: 2024-07-02T19:36:34Z
  GitCommit: e1284e19e03c9abab2ea55314b14b1e0381c4045
  GitTreeState: clean
  GoVersion: go1.21.11
  Compiler: gc
  Platform: darwin/arm64
argocd-server: v2.4.3+471685f
  BuildDate: 2022-06-27T21:02:55Z
  GitCommit: 471685feae063c1c2e36a5ff268c4da87c697b85
  GitTreeState: clean
  GoVersion: go1.18.3
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: v4.4.1 2021-11-11T23:36:27Z
  Helm Version: v3.8.1+g5cb9af4
  Kubectl Version: v0.23.1
  Jsonnet Version: v0.18.0
agaudreault commented 5 days ago

Hmmm, you have your application configured to auto-sync with the configuration

      syncPolicy:
        automated:
          prune: true
          selfHeal: true
          allowEmpty: false

But you are also calling an argo API to perform the sync. My guess would be that sometime auto-sync triggers automatically around the same time you request the sync. I think logs of the application-controller would be required to know which sync is not using the correct commit ID. I assume targetRevision: '{{ source.targetRevision }}' resolves to targetRevision: cicd. Is this a branch or a tag that is updated?