CAPA — Argo 프로젝트 인증 어소시에이트 · Argo 프로젝트 전체 조망 · 이론
Argo 는 왜 넷으로 쪼개졌나
한 줄 요약
Argo 는 배포 도구 하나가 아니라 네 개의 CNCF 프로젝트 묶음이다. Argo CD 는 "클러스터가 Git 과 같은 상태인가", Workflows 는 "이 작업들을 정해진 순서로 끝까지 돌려라", Events 는 "바깥에서 무슨 일이 생기면 그때", Rollouts 는 "새 버전을 얼마나 천천히 내보낼까" 를 각각 푼다. 네 개를 하나로 합치지 않은 이유는 각자가 다루는 시간의 성격이 다르기 때문이다.
왜 이게 필요했나
GitOps 이전의 배포는 대부분 푸시였다. CI 서버가 빌드를 끝내고 kubectl apply 를 때린다. 이 구조에는 세 가지 값이 숨어 있다. 첫째, CI 서버가 프로덕션 클러스터의 자격 증명을 들고 있어야 한다. 젠킨스 한 대가 뚫리면 모든 클러스터가 뚫린다. 둘째, 적용한 뒤에 누가 손으로 replicas 를 바꿔도 아무도 모른다. Git 은 배포 시점의 기록일 뿐 현재 상태의 근거가 아니다. 셋째, 클러스터가 여러 개가 되는 순간 파이프라인이 클러스터 수만큼 늘어난다.
풀 모델은 이 셋을 한 번에 뒤집는다. 클러스터 안에 사는 컨트롤러가 Git 을 읽고 스스로 맞춘다. 자격 증명은 밖으로 나가지 않고, 컨트롤러가 계속 비교하니 드리프트가 상태로 드러나며, 클러스터가 늘어도 Git 저장소는 하나다. Argo CD 가 하는 일이 정확히 이것이고, 나머지 셋은 이 축을 중심으로 붙은 위성이다.
어떻게 동작하나
| 프로젝트 | 푸는 문제 | 시간의 성격 |
| --- | --- | --- |
| Argo CD | 선언한 상태와 실제 상태의 차이를 계속 지운다 | 끝나지 않는 루프 (기본 180초 주기) |
| Argo Workflows | 여러 컨테이너 작업을 DAG 로 엮어 한 번 완주시킨다 | 시작과 끝이 있는 유한한 실행 |
| Argo Events | 외부 신호를 받아 무언가를 시작시킨다 | 언제 올지 모르는 이벤트 |
| Argo Rollouts | 새 버전을 지표를 보며 조금씩 늘린다 | 사람의 판단이 끼어드는 몇 분에서 몇 시간 |
합치지 않은 이유가 여기서 보인다. Argo CD 는 "차이가 0 이 될 때까지" 도는 물건이라 완료 개념이 없다. Workflows 는 반대로 완료가 전부다. 이 둘을 한 컨트롤러에 넣으면 재시도 의미도, 실패 처리도, 메트릭 이름도 전부 충돌한다. Events 가 따로 있는 것도 같은 이유다. Argo CD 에 웹훅 처리를 넣기 시작하면 GitHub, S3, Kafka, 캘린더까지 전부 배포 컨트롤러 안으로 들어온다. Events 는 그 어댑터 지옥을 EventSource → Sensor → Trigger 라는 별도 축으로 빼낸 것이다.
Argo CD 는 CNCF Graduated 프로젝트다. 졸업 등급이 뜻하는 실무적 함의는 "이 API 가 다음 분기에 갈아엎히지 않는다" 이고, 그래서 Application 매니페스트를 조직 표준으로 삼아도 괜찮다는 판단의 근거가 된다.
현장에서 만나는 모습
저자의 홈랩은 컨트롤 플레인 3대와 GPU 워커 4대, 합쳐서 7노드다. MetalLB 가 10.0.0.200부터 215까지를 L2 로 나눠 주고 그 위에 Gitea 가 10.0.0.200, ArgoCD 가 10.0.0.201, Harbor 가 10.0.0.202 로 떠 있다. 소스와 GitOps 컨트롤러와 레지스트리가 같은 주소 대역 안에 나란히 있는 셈인데, 이 배치의 진짜 값어치는 장애가 났을 때 드러났다.
이 클러스터는 controlPlaneEndpoint 가 VIP 가 아니라 첫 컨트롤 플레인의 물리 IP 로 박혀 있었다. etcd 멤버는 3개라 쿼럼은 멀쩡한데, 그 노드가 죽으면 kubectl 도 kubelet 도 전부 접속 불가가 된다. 컨트롤 플레인은 살아 있는데 아무도 문을 못 찾는 상태다. 여기서 배운 것이 두 가지인데, 하나는 "상태가 Ready 인 것과 실제로 동작하는 것은 다른 명제" 라는 것이고, 다른 하나는 클러스터가 통째로 안 보이는 동안에도 Git 저장소에는 원하는 상태가 그대로 남아 있었다는 것이다. 푸시 파이프라인이었다면 복구 절차가 "파이프라인을 다시 짠다" 였겠지만, 풀 모델에서는 클러스터를 되살리는 순간 컨트롤러가 알아서 따라잡는다. GitOps 를 도입하는 이유를 배포 편의로 설명하는 글이 많은데, 실제로 값어치가 드러나는 순간은 이런 복구 시점이다.
다음 퀴즈에서 확인할 것
이 모듈은 개념만 다룬다. 바로 이어지는 모듈에서 Application 매니페스트를 직접 쓰면서, 방금 말한 "차이를 계속 지우는 루프" 가 어떤 필드들로 조립되는지 손으로 확인한다.