IT/CI CD

ArgoCD 3.0 마이그레이션, 우리가 부쉈던 것들

gfrog 2026. 5. 25. 15:14
반응형

지난주에 우리 팀 dev/staging 클러스터의 ArgoCD를 2.14에서 3.0으로 올렸다. 공식 블로그에서는 "small but mighty"라고 했고, 업그레이드 노트도 "low-risk upgrade"라고 적혀 있길래 점심 먹기 전에 끝낼 수 있을 줄 알았다. 근데 점심을 굶었다. 그리고 저녁도 거의 굶을 뻔했다.

운영 클러스터 올리기 전에 dev에서 한 번 더 정리하고 가는 게 좋을 것 같아서, 우리가 어디서 발이 걸렸는지 기록으로 남긴다. 공식 문서가 빠뜨린 건 없는데, 문서가 짧고 담백해서 "어 이게 진짜 우리한테 영향 있나?" 라고 흘려 보기 쉽다. 우리는 흘려 봤고 결과는 위 문단대로다.

첫 번째 지뢰: logs RBAC 강제

3.0부터 logs RBAC enforcement가 default로 켜진다. 이게 무슨 말이냐면, 2.x에서는 어플리케이션을 볼 수 있는 사람이면 그 어플리케이션 소속 파드 로그도 그냥 봤다. 3.0에서는 logs, get 권한이 RBAC에 따로 명시돼 있어야 한다.

업그레이드 직후 오후 2시쯤 슬랙이 울리기 시작했다.

"어 ArgoCD에서 파드 로그가 안 뜨는데요?"
"저도요"
"Permission denied 떠요"

개발자들 워크플로 절반이 ArgoCD UI에서 파드 로그 보면서 디버깅하는 거였는데, 그게 한 번에 다 막혔다. 처음에는 클러스터 권한이 깨졌나 했다. 아니었다. ArgoCD 자체 RBAC가 막은 거였다.

해결은 단순하다. argocd-rbac-cm에 다음을 추가:

data:
  policy.csv: |
    p, role:developer, logs, get, */*, allow
    p, role:developer, exec, create, */*, allow  # exec도 같은 문제 겪을 수 있음
    g, your-dev-group, role:developer

근데 단순한 만큼, 업그레이드 전에 RBAC 정책을 미리 만들어 두지 않으면 무조건 한 번은 알람이 온다. 우리는 그걸 운영 클러스터에서는 피하고 싶다.

두 번째 지뢰: Resource tracking label → annotation

이게 제일 무서웠다. 2.x에서는 default tracking method가 label이었다. 3.0에서는 annotation이 default다.

문서에는 "migrate to annotation-based tracking"이라고 한 줄 적혀 있다. 한 줄. 근데 이걸 안 하고 그냥 올리면 무슨 일이 벌어지냐면, ArgoCD가 기존에 관리하던 리소스들을 자기 게 아니라고 판단한다. Out of sync로 잡히고, sync 누르면 새 리소스를 또 만들려고 한다. Duplicate.

우리는 다행히 dev 클러스터라서 sync 누르기 전에 뭔가 이상하다는 걸 알아챘다. 모든 Application이 OutOfSync로 떠 있고 진단을 보면 "Resource not managed by this Application"이라는 문구가 나왔다. 거기서 멈췄다.

해결 순서는 이렇다:

  1. 업그레이드 전에 application.resourceTrackingMethod: annotation+label로 설정. 이게 dual write 모드다. 둘 다 박는다.
  2. ArgoCD가 한 바퀴 reconcile 돌면서 모든 관리 리소스에 annotation을 새로 박는다. 시간 좀 걸린다. 우리 환경은 약 800개 Application에 25분 정도.
  3. 모든 리소스에 annotation이 박힌 걸 확인한 다음 application.resourceTrackingMethod: annotation으로 변경.
  4. 그 다음에 3.0 업그레이드.

우리는 3을 건너뛰고 바로 3.0을 올렸다가 위 사단이 났다. 다행히 dual write 상태로 annotation이 박힌 리소스들은 살아 있었기 때문에, tracking method를 annotation으로 명시한 다음 ArgoCD를 재시작하니까 인식이 돌아왔다. 운이 좋았다.

세 번째 지뢰: Grafana 대시보드가 비어버렸다

이건 다음 날 아침에 발견했다. ArgoCD 모니터링 대시보드를 열었는데 패널 절반이 비어 있었다. argocd_app_sync_status, argocd_app_health_status, argocd_app_created_time 메트릭이 3.0에서 삭제됐다.

대신 argocd_app_info에 label로 들어간다. 그러니까 PromQL을 새로 쓰는 게 아니라 기존 쿼리를 label 기반으로 바꿔야 한다.

이전:

sum(argocd_app_sync_status{sync_status="OutOfSync"})

이후:

sum(argocd_app_info{sync_status="OutOfSync"})

뭐 어렵진 않다. 근데 우리는 사내에 ArgoCD 대시보드가 4개 있었고, 각 대시보드가 패널 12-15개씩 있었다. 50개 가까운 PromQL을 다 수정했다. 한 시간 반 걸렸다.

배포 알람으로 쓰던 Alertmanager rule도 같이 깨졌다는 걸 그 다음에 알아챘다. SLO 알람이 안 울리는 게 더 무서운 상황이라는 걸 그때 다시 한 번 느꼈다.

네 번째: 의외로 안 깨진 것

ApplicationSet의 matrix/merge generator에서 applyNestedSelectors: true가 default가 된 것 — 이게 우리한테 영향 줄 줄 알았는데, 우리가 쓰던 매트릭스 패턴이 nested selector를 안 썼다. 다행히.

근데 ApplicationSet PR generator 같은 거 nested하게 짠 팀은 여기서 한 번 더 터질 수 있을 거다. 특히 cluster generator + git generator 매트릭스 조합.

운영 올리기 전에 우리가 다시 정리한 것

dev에서 한 번 부서지고 나니까 운영용 체크리스트가 생겼다:

  • argocd-cm에 legacy repository config 남아 있는지 grep (repositories: 키)
  • tracking method를 annotation+label로 먼저 바꾼 다음 24시간 대기
  • 모든 Application 리소스에 argocd.argoproj.io/tracking-id annotation이 박혔는지 샘플링 확인
  • RBAC에 logs, get / exec, create 미리 추가
  • Grafana 대시보드 PromQL 새 메트릭 기준으로 미리 PR 띄워두기
  • Alertmanager rule도 같이
  • cluster.inClusterEnabled 명시적으로 false로 막혀 있는 게 있는지 확인

운영은 다음 주 화요일에 정비 윈도우 잡고 한다. 이번엔 점심 먹을 수 있을 것 같다.

마무리

ArgoCD 3.0이 진짜로 작은 업그레이드인 건 맞다. 깨지는 항목 자체는 적다. 근데 깨지는 방식이 sneaky하다. 알람이 즉시 오는 게 아니라 사용자가 "어 이거 왜 안 보여요?" 하는 식으로 발견된다. 모니터링이 조용히 깨져 있는 게 제일 무섭다는 걸 다시 배웠다.

혹시 비슷한 마이그레이션 앞두고 계신 분 있으면, tracking method dual write를 먼저 켜두는 것 하나만 챙기셔도 절반은 안전합니다. 다른 거 부서져도 그건 즉시 알아챌 수 있는데, tracking method는 sync 누르는 순간 진짜 큰 일 납니다.

반응형