Sync Phases and Waves — 리소스를 넣는 순서를 내 마음대로

Sync Phases and Waves — 리소스를 넣는 순서를 내 마음대로

배포할 때 어떤 리소스가 먼저 적용돼야 하는지, 잡이나 워크플로를 중간에 실행해야 하는지 정하고 싶을 때가 있어요. Argo CD는 **싱크 페이즈(Phases)**와 **싱크 웨이브(Waves)**라는 두 가지 방식으로 이 순서를 조정하게 해 줍니다.

출처: Argo CD 공식 문서 — Sync Phases and Waves

본문

싱크 페이즈와 훅은 '리소스를 본 싱크의 앞뒤 중 언제 적용할지'를 정의해요. 덕분에 잡이나 다른 리소스를 특정 순서로 실행하거나 적용할 수 있습니다.

훅 타입

리소스에 argocd.argoproj.io/hook 애노테이션을 붙이면 그 페이즈에 배정돼요. 훅은 어떤 쿠버네티스 리소스 kind든 될 수 있지만, 주로 Pod·Job·Argo Workflows가 쓰여요. 여러 개는 콤마로 이어 붙일 수 있습니다.

설명
PreSync 매니페스트를 적용하기 전에 실행돼요.
Sync 모든 PreSync 훅이 성공적으로 끝난 뒤, 매니페스트 적용과 동시에 실행돼요.
Skip Argo CD가 해당 매니페스트를 적용하지 않도록 표시해요.
PostSync 모든 Sync 훅이 성공하고, 모든 리소스가 Healthy 상태가 된 뒤 실행돼요.
SyncFail 싱크 연산이 실패했을 때 실행돼요.
PreDelete Application 리소스가 삭제되기 전에 실행돼요. 프루닝을 켜도 일반 싱크에서는 돌지 않고, Application 전체 삭제 때만 돼요.
PostDelete 모든 Application 리소스가 삭제된 뒤 실행돼요. v2.10부터 지원합니다.

페이즈는 어떻게 동작하나

싱크 도중 Argo CD는 아래 순서로 진행해요.

  1. PreSync 훅을 모두 적용. 하나라도 실패하면 전체 싱크가 중단되고 실패로 표시돼요.
  2. Sync 훅을 모두 적용. 실패하면 전체가 실패로 표시되고 SyncFail 훅도 함께 실행돼요.
  3. PostSync 훅을 모두 적용. 실패하면 역시 전체 실패예요.

Skip으로 표시된 리소스는 적용되지 않아요. 이 단순한 수명주기는 여러 상황에 쓸 수 있어요. 필수 체크를 PreSync 훅으로 걸어두면, 그게 실패할 때 배포 자체가 진행되지 않으니 안전 문처럼 동작해요. 반대로 스모크 테스트를 PostSync 훅으로 돌리면 성공 여부로 검증을 확인할 수 있죠.

훅은 selective sync 중에는 실행되지 않아요. SyncFail 페이즈 동안 훅으로 정리(cleanup) 같은 작업을 할 수 있고, SyncFail 훅 자신이 실패해도 추가 조치는 없이 전체 연산만 실패로 남습니다. 프루닝 때는 생성 순서와 반대로 웨이브가 높은 리소스부터 지워져요. 어떤 웨이브의 프루닝이 실패하면 연산이 실패로 표시되고 낮은 웨이브는 처리되지 않아, 의존 리소스가 올바른 순서로 삭제되게 보장합니다.

훅 수명주기와 정리

argocd.argoproj.io/hook-delete-policy로 훅이 언제 삭제될지 정할 수 있어요.

정책 설명
HookSucceeded 싱크가 성공하면 훅 리소스를 삭제. Job·Workflow 같은 완료형 훅은 보통 완료 후에 삭제돼요.
HookFailed 훅이 실패한 뒤 삭제해요.
BeforeHookCreation 새 훅을 만들기 전에 기존 훅을 삭제 (v1.3부터). /metadata/name과 함께 쓰기 좋아요.

삭제 정책을 지정하지 않으면 기본적으로 BeforeHookCreation 규칙이 적용됩니다.

싱크 웨이브 — argocd.argoproj.io/sync-wave

훅 말고도 argocd.argoproj.io/sync-wave 애노테이션으로 순서를 바꿀 수 있어요. 값은 정수이고, Argo CD는 낮은 숫자부터 높은 숫자 순으로 배포합니다.

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "5"

훅과 리소스는 기본적으로 웨이브 0에 배정돼요. 웨이브 값은 음수도 가능해서, 다른 모든 리소스보다 먼저 실행할 웨이브를 만들 수도 있습니다. 같은 웨이브 값을 가진 리소스는 함께 처리되고, 웨이브 안에서는 kind(예: 네임스페이스 먼저) 다음 이름 순으로 정렬돼요.

싱크 연산이 시작되면 Argo CD는 리소스를 다음 우선순위로 정렬합니다.

  1. 페이즈
  2. 웨이브 (생성·갱신은 낮은 값 먼저, 삭제는 높은 값 먼저)
  3. kind (네임스페이스 → 일반 쿠버네티스 리소스 → 커스텀 리소스)
  4. 이름

그다음 적용할 첫 웨이브를 찾는데, 이때 아웃오브싱크이거나 언헬시한 리소스가 있는 가장 낮은 번호의 웨이브가 기준이 돼요. 그 웨이브를 적용하고, 모든 페이즈·웨이브가 싱크·헬시가 될 때까지 반복합니다. 첫 웨이브에 이미 언헬시한 리소스가 있으면 앱이 영영 헬시에 못 이를 수도 있어 주의가 필요해요.

각 싱크 웨이브 사이에는 다른 컨트롤러가 반응할 시간을 주기 위한 지연이 있어요. 기본 2초이고, argocd-application-controller 디플로이먼트의 ARGOCD_SYNC_WAVE_DELAY 환경변수로 조정할 수 있습니다.

페이즈는 크게, 웨이브는 세밀하게

싱크 웨이브만 단독으로 쓸 수도 있지만, 훅(페이즈)으로 큰 순서를 잡고 웨이브로 페이즈 안의 세부 순서를 정하면 가장 유연해요.

예를 들어 DB 초기화·마이그레이션 잡을 본 싱크 전에(또한 웨이브 -1에서) 돌리고 싶다면:

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
    argocd.argoproj.io/sync-wave: '-1'
spec:
  ttlSecondsAfterFinished: 360
  template:
    spec:
      containers:
        - name: postgresql-client
          image: 'my-postgres-data:11.5'
          command:
            - psql
            - '-h=my_postgresql_db'
            - '-U postgres'
            - '-f preload.sql'
      restartPolicy: Never
  backoffLimit: 1

이렇게 하면 매니페스트가 적용되기 전에 스키마가 준비되어 있어요.

더 알아보기 (Learn more)