점진적 동기화

점진적 동기화 (Progressive Syncs)

점진적 동기화는 ApplicationSet 컨트롤러가 ApplicationSet 리소스가 소유한 Application을 생성·업데이트하는 순서를 제어할 수 있게 해주는 기능이에요. 관리되는 Application이 "Healthy"가 되기 전까지 다음 단계로 진행하지 않아요. 3.3.0부터 제공되는 베타 기능이에요.

출처: 문서

본문

경고 — 베타 기능 (v3.3.0부터)

이 기능은 Beta 단계예요. 일반적으로 안정적이라고 간주되지만, 처리되지 않은 엣지 케이스가 있을 수 있어요. 이 기능은 ApplicationSet 리소스가 소유한 Application을 ApplicationSet 컨트롤러가 생성·업데이트하는 순서를 제어할 수 있게 해요.

사용 사례 (Use Cases)

Progressive Syncs 기능 묶음은 가볍고 유연하게 설계되었어요. 이 기능은 관리되는 Application의 health와만 상호작용해요. 다른 Rollout 컨트롤러(네이티브 ReplicaSet 컨트롤러나 Argo Rollouts 같은)와 직접 통합하는 것은 지원하지 않아요.

  • Progressive Syncs는 관리되는 Application 리소스가 "Healthy"가 되기를 기다린 다음 다음 단계로 진행해요.
  • Deployments, DaemonSets, StatefulSets, Argo Rollouts이 모두 지원돼요. 파드가 롤아웃되는 동안 Application이 "Progressing" 상태로 들어가기 때문이에요. 실제로 "Progressing" 상태를 보고할 수 있는 health check가 있는 어떤 리소스든 지원돼요.
  • Argo CD Resource Hooks가 지원돼요. Argo Rollout을 사용할 수 없을 때 고급 기능이 필요한 사용자(예: DaemonSet 변경 후 스모크 테스트)에게는 이 접근 방식을 권장해요.

점진적 동기화 활성화 (Enabling Progressive Syncs)

실험적 기능이므로 점진적 동기화는 다음 방법 중 하나로 명시적으로 활성화해야 해요.

  1. ApplicationSet 컨트롤러 인자에 --enable-progressive-syncs 전달.
  2. ApplicationSet 컨트롤러 환경 변수에 ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS=true 설정.
  3. Argo CD argocd-cmd-params-cm ConfigMap에 applicationsetcontroller.enable.progressive.syncs: "true" 설정.

전략 (Strategies)

ApplicationSet 전략은 애플리케이션이 생성(또는 업데이트)·삭제되는 방식을 모두 제어해요. 이 작업들은 두 개의 별도 필드로 구성돼요.

  • 생성 전략(Creation Strategy) (type 필드): 애플리케이션 생성과 업데이트 제어
  • 삭제 전략(Deletion Strategy) (deletionOrder 필드): 애플리케이션 삭제 순서 제어

생성 전략 (Creation Strategies)

type 필드는 애플리케이션이 생성·업데이트되는 방식을 제어해요. 사용 가능한 값:

  • AllAtOnce (기본값)
  • RollingSync
AllAtOnce

이 기본 Application 업데이트 동작은 원래 ApplicationSet 구현에서 바뀌지 않았어요.

ApplicationSet 리소스가 업데이트되면 그 리소스가 관리하는 모든 Application이 동시에 업데이트돼요.

spec:
  strategy:
    type: AllAtOnce # explicit, but this is the default
RollingSync

이 업데이트 전략은 생성된 Application 리소스에 있는 라벨로 Application을 그룹화할 수 있게 해요. ApplicationSet이 변경되면 각 Application 리소스 그룹에 변경이 순차적으로 적용돼요.

  • Application 그룹은 라벨과 matchExpressions로 선택돼요.
  • Application이 선택되려면 모든 matchExpressions가 참이어야 해요(여러 표현식은 AND 동작으로 매칭).
  • InNotIn 연산자는 하나 이상의 값을 매칭해야 참으로 간주돼요(OR 동작).
  • NotInIn 연산자가 모두 매치를 만들면 NotIn 연산자에 우선권이 있어요.
  • 각 그룹의 모든 Application이 Healthy가 되기 전까지 ApplicationSet 컨트롤러는 다음 Application 그룹을 업데이트하지 않아요.
  • 그룹에서 동시 Application 업데이트 수는 maxUpdate 파라미터(기본값은 100%, 무제한)를 초과하지 않아요.
  • RollingSync는 관리되는 Application의 OutOfSync 상태를 감시하므로 ApplicationSet 리소스 외부의 변경도 포착해요.
  • RollingSync는 생성된 모든 Application이 autosync를 비활성화하도록 강제해요. 자동 syncPolicy가 활성화된 Application spec에 대해서는 applicationset-controller 로그에 경고가 출력돼요.
  • Sync 작업은 UI나 CLI로 트리거한 것과 같은 방식으로 트리거돼요(Application 리소스의 operation 상태 필드를 직접 설정). 즉 RollingSync는 사용자가 Argo UI에서 "Sync" 버튼을 클릭한 것처럼 sync windows를 존중해요.
  • sync가 트리거되면 Application에 구성된 것과 같은 syncPolicy로 sync가 수행돼요. 예를 들어 Application의 retry 설정을 보존해요.
  • 어떤 Application이 어느 단계에도 선택되지 않으면 그 Application은 롤링 sync에서 제외되며 CLI나 UI로 수동 sync해야 해요.
spec:
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-dev
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-prod
          maxUpdate: 10%

위 예시에서는 sync가 두 단계로 수행돼요.

  1. envLabel=env-dev 라벨을 가진 모든 Application이 먼저 sync되도록 선택돼요. maxUpdate가 정의되지 않았으므로 기본값 100%가 적용되어 매치된 모든 Application이 동시에 sync돼요. 컨트롤러는 선택된 모든 Application이 Healthy 상태가 될 때까지 기다린 다음 다음 단계로 진행해요.
  2. 다음으로 envLabel=env-prod 라벨을 가진 Application이 sync되도록 선택돼요. 여기서는 매치된 Application의 10%만 한 번에 sync돼요. 각 Application 배치가 Healthy 상태가 되면 다음 배치가 sync되며 모든 매치된 Application이 sync될 때까지 계속돼요.

나열된 표현식과 매치되지 않는 Application이 있으면 RollingSync 전략으로 sync되지 않으며 위에서 설명한 대로 수동 sync해야 해요.

삭제 전략 (Deletion Strategies)

deletionOrder 필드는 Application이 ApplicationSet에서 제거될 때 삭제되는 순서를 제어해요. 사용 가능한 값:

  • AllAtOnce (기본값)
  • Reverse
AllAtOnce 삭제 (AllAtOnce Deletion)

이것은 삭제해야 할 모든 애플리케이션이 동시에 제거되는 기본 동작이에요. AllAtOnceRollingSync 생성 전략 모두에서 동작해요.

spec:
  strategy:
    type: RollingSync # or AllAtOnce
    deletionOrder: AllAtOnce # explicit, but this is the default
Reverse 삭제 (Reverse Deletion)

RollingSync 전략에서 deletionOrder: Reverse를 사용하면, 애플리케이션이 rollingSync.steps에 정의된 단계의 역순으로 삭제돼요. 이렇게 하면 나중 단계에서 배포된 애플리케이션이 더 이른 단계에서 배포된 애플리케이션보다 먼저 삭제돼요. 이 전략은 종속 서비스를 특정 순서로 철거(tear down)해야 할 때 특히 유용해요.

Reverse 삭제 요구 사항:

  • type: RollingSync와 함께 사용해야 해요.
  • rollingSync.steps가 정의되어야 해요.
  • 애플리케이션이 단계 순서의 역순으로 삭제돼요.

중요: 모든 애플리케이션이 성공적으로 삭제될 때까지 ApplicationSet finalizer는 제거되지 않아요. 이는 적절한 정리를 보장하고 ApplicationSet이 관리하는 애플리케이션보다 먼저 제거되는 것을 방지해요.

참고: ApplicationSet 컨트롤러는 점진적 sync가 활성화된 상태에서 deletionOrderReverse로 설정되면 finalizer가 있는지 확인해요. 즉 applicationset에 필요한 finalizer가 없으면, applicationset 컨트롤러는 애플리케이션을 생성하기 전에 ApplicationSet에 finalizer를 추가해요.

spec:
  strategy:
    type: RollingSync
    deletionOrder: Reverse
    rollingSync:
      steps:
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-dev # Step 1: Created first, deleted last
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-prod # Step 2: Created second, deleted first

이 예시에서 애플리케이션이 삭제될 때:

  1. env-prod 애플리케이션(Step 2)이 먼저 삭제돼요.
  2. env-dev 애플리케이션(Step 1)이 두 번째로 삭제돼요.

이 삭제 순서는 백엔드 종속성 이전에 프런트엔드 서비스를 삭제하는 것처럼, 종속 서비스를 올바른 순서로 철거해야 하는 시나리오에 유용해요.

예시 (Example)

다음 예시는 명시적으로 구성된 환경 라벨을 가진 Application들에 걸쳐 점진적 sync를 단계별로 진행하는 방법을 보여줘요.

변경이 푸시되면 다음 순서로 진행돼요.

  • 모든 env-dev Application이 동시에 업데이트돼요.
  • 롤아웃은 모든 env-qa Application이 argocd CLI나 UI의 Sync 버튼 클릭으로 수동 sync될 때까지 기다려요.
  • 모든 env-prod Application이 업데이트될 때까지 env-prod Application의 10%가 한 번에 업데이트돼요.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
spec:
  generators:
    - list:
        elements:
          - cluster: engineering-dev
            url: https://1.2.3.4
            env: env-dev
          - cluster: engineering-qa
            url: https://2.4.6.8
            env: env-qa
          - cluster: engineering-prod
            url: https://9.8.7.6/
            env: env-prod
  strategy:
    type: RollingSync
    deletionOrder: Reverse # Applications will be deleted in reverse order of steps
    rollingSync:
      steps:
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-dev
          #maxUpdate: 100%  # if undefined, all applications matched are updated together (default is 100%)
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-qa
          maxUpdate: 0 # if 0, no matched applications will be updated
        - matchExpressions:
            - key: envLabel
              operator: In
              values:
                - env-prod
          maxUpdate: 10% # maxUpdate supports both integer and percentage string values (rounds down, but floored at 1 Application for >0%)
  goTemplate: true
  goTemplateOptions: ['missingkey=error']
  template:
    metadata:
      name: '{{.cluster}}-guestbook'
      labels:
        envLabel: '{{.env}}'
    spec:
      project: my-project
      source:
        repoURL: https://github.com/infra-team/cluster-deployments.git
        targetRevision: HEAD
        path: guestbook/{{.cluster}}
      destination:
        server: '{{.url}}'
        namespace: guestbook

maxUpdate는 정수와 퍼센트 문자열 값을 모두 지원하며(내림, 단 0% 초과 시 최소 1 Application), 0이면 매치된 Application을 업데이트하지 않아요.

더 알아보기 (Learn more)