Argo CD 환경에서 발생하는 'Stale' 상태 장애?

수천 개의 마이크로서비스를 Argo CD로 관리하는 환경에서, 간헐적인 네트워크 문제나 API 서버 과부하로 인해 Git 리포지토리와의 연결이 잠시 끊겼다가 복구된 후 다수의 애플리케이션이 ‘Progressing’ 상태에 멈춰버리는 ‘Stale’ 현상이 발생합니다. 실제 워크로드는 정상적으로 배포되어 Healthy 상태이지만, Argo CD의 UI와 상태는 동기화되지 않아 운영상 혼란을 초래합니다. 수천 개의 애플리케이션을 일일이 수동으로 'Refresh’나 ‘Sync’ 할 수 없는 상황에서, 이러한 Stale 상태를 자동으로 감지하고 해결할 수 있는 효율적인 자동화 방안은 무엇일까요?

[CloudBro AI Bot Response]

Argo CD Stale 상태 자동 감지 및 해결 방안

수천 개의 마이크로서비스를 Argo CD로 관리하는 환경에서, 네트워크 문제나 API 서버 과부하로 인한 ‘Stale’(Progressing 상태 멈춤) 현상은 운영상 큰 혼란을 초래합니다. 실제 워크로드는 정상인데 UI와 상태가 동기화되지 않아, 일일이 수동 조치가 불가능한 상황에서 자동화 방안을 제안드립니다.

1. 문제 원인 및 현상 정리

  • 원인: Git 리포지토리와 Argo CD API 서버 간 연결이 일시적으로 끊겼다가 복구되면서 상태 동기화가 제대로 이루어지지 않음.
  • 결과: 애플리케이션 상태가 Progressing에 멈추고, UI는 실제 상태와 불일치.
  • 운영 영향: 수천 개 앱을 수동으로 Refresh/Sync 불가, 상태 모니터링 및 장애 대응 어려움.

2. 권장 자동화 아키텍처 및 구현 전략

(1) Argo CD CLI / API 활용한 자동 상태 점검 및 Refresh/Sync 자동화

  • Argo CD는 REST API 및 CLI(argocd app)를 제공하며, 이를 통해 애플리케이션 상태를 조회하고 refresh 또는 sync 명령을 자동 실행할 수 있습니다.
  • 핵심 아이디어: 일정 주기(예: 5~15분)로 모든 애플리케이션 상태를 스크립트로 조회 → Progressing 상태가 일정 시간 이상 지속된 앱에 대해 자동 Refresh/Sync 실행.

예시: Bash 스크립트 (argocd CLI 활용)

#!/bin/bash

# Argo CD 로그인 (토큰 또는 로그인 명령 필요)
argocd login <ARGOCD_SERVER> --username <USER> --password <PASSWORD> --insecure

# 모든 애플리케이션 리스트 조회
apps=$(argocd app list -o name)

for app in $apps; do
  status=$(argocd app get $app -o json | jq -r '.status.sync.status')
  health=$(argocd app get $app -o json | jq -r '.status.health.status')
  # Progressing 상태 감지 (예: Sync 상태가 OutOfSync이거나 Health가 Progressing)
  if [[ "$status" == "OutOfSync" ]] || [[ "$health" == "Progressing" ]]; then
    echo "Refreshing app: $app (status: $status, health: $health)"
    argocd app refresh $app
    # 필요시 sync까지 수행
    # argocd app sync $app
  fi
done
  • 위 스크립트를 Kubernetes CronJob, Jenkins, GitHub Actions, Argo Workflow 등에서 주기적으로 실행 가능.
  • jq를 활용해 JSON 파싱, 조건에 따른 필터링 가능.

(2) Argo CD Notifications 및 Webhook 연동

  • Argo CD Notifications를 활용해 상태 변화 이벤트를 받아 Slack, 이메일 등으로 알림.
  • 알림과 연동해 Lambda 함수, Cloud Run, 서버리스 스크립트 등에서 자동 Refresh/Sync API 호출 가능.

(3) Argo CD ApplicationSet + GitOps 패턴 활용

  • ApplicationSet 컨트롤러를 이용해 애플리케이션 그룹별로 상태를 관리하고, 상태 이상시 자동 재배포 트리거 가능.
  • GitOps 방식으로 상태 정의를 Git에 보관해 상태 불일치 최소화.

(4) CNCF 및 커뮤니티 참고 리소스


3. 추가 운영 팁 및 트러블슈팅

문제 상황 원인 및 해결책
argocd app refresh 실패 네트워크 문제, 인증 만료 확인 후 재로그인 필요
CLI 버전 불일치 Argo CD 서버와 CLI 버전 맞추기 (주기적 업그레이드 권장)
API Rate Limit 초과 호출 주기 조절 및 병렬 호출 제한, 백오프(backoff) 로직 도입 추천
대규모 애플리케이션 부하 ApplicationSet 및 그룹별 배치 처리로 병목 완화

4. 요약 및 권장 실행 단계

  1. 자동 상태 점검 스크립트 작성 및 주기적 실행 (CronJob, CI/CD 파이프라인 등)
  2. 상태 이상 애플리케이션에 대해 argocd app refresh 자동 실행
  3. 필요시 sync 자동화 추가 (신중히 적용)
  4. Argo CD Notifications 및 Webhook과 연동해 모니터링 강화
  5. ApplicationSet 등 Argo CD 최신 기능 활용해 운영 효율성 극대화

필요시 구체적인 스크립트 작성, Kubernetes CronJob 배포 예제, Argo CD API 인증 설정 방법 등 추가 가이드도 제공 가능합니다.
운영 환경에 맞춰 단계별로 적용해 보시길 권장 드립니다.


궁금한 점이나 추가 요청 사항 있으시면 언제든 문의 주세요!


참고: Argo CD는 CNCF 프로젝트로, 최신 공식 문서와 GitHub 이슈를 꾸준히 모니터링하는 것이 안정적인 운영에 큰 도움이 됩니다.

이 문제는 대규모 Kubernetes 환경에서 Argo CD를 운영할 때 직면할 수 있는 대표적인 동기화 문제입니다. 참고 자료 : https://www.cncf.io/wp-content/uploads/2025/04/cncf_annual_survey24_031225a.pdf

해결 방안은 단순히 Argo CD의 설정을 조정하는 것을 넘어, Kubernetes의 커스텀 리소스와 오퍼레이터 패턴을 활용한 자동화 로직을 구현하는 방향으로 접근해야 합니다.

  • Argo CD Application Controller의 타임아웃 설정 조정: 우선적으로 argocd-cm ConfigMap에서 timeout.reconciliation 값을 늘려 일시적인 네트워크 불안정성에 대한 내성을 높일 수 있습니다. 하지만 이는 근본적인 해결책이 아닌 임시방편에 가깝습니다.

  • Kubernetes CronJob을 이용한 주기적인 강제 동기화: 가장 현실적인 접근법은 Kubernetes의 CronJob을 이용해 주기적으로 Stale 상태의 Argo CD 애플리케이션을 찾아 강제로 동기화(hard refresh)하는 것입니다.

    1. 대상 선정 스크립트 작성: Argo CD CLI나 Kubernetes API를 사용하여 특정 시간(예: 30분) 이상 ‘Progressing’ 상태에 머물러 있는 애플리케이션 목록을 조회하는 셸 스크립트나 파이썬 스크립트를 작성합니다. 이때 creationTimestamp와 현재 시간을 비교하고, status.health.status가 Healthy이지만 status.sync.statusOutOfSync이거나 status.operationState.phaseRunning인 경우를 Stale 상태로 정의할 수 있습니다.

    2. CronJob 생성: 이 스크립트를 실행하는 컨테이너 이미지를 만들고, Kubernetes CronJob으로 등록하여 1시간 등 특정 주기마다 실행되도록 설정합니다.

    3. 강제 동기화 실행: 스크립트는 조회된 Stale 애플리케이션들에 대해 argocd app patch-resource 명령어나 API 호출을 통해 리소스에 특정 어노테이션(예: force-refresh=timestamp)을 추가하거나 변경합니다. 이 변경 사항은 Argo CD가 해당 애플리케이션을 강제로 재조정(reconciliation)하게 만드는 트리거 역할을 합니다.

이러한 접근은 수동 개입을 최소화하고 GitOps 파이프라인의 신뢰성을 대규모 환경에서도 유지할 수 있게 해주는 효과적인 SRE라고 생각합니다. :slight_smile:

1 Like