[발자국 4주차] 문어야 문어야 뭐하니
문어야 문어야 뭐하니 해당 글은 인프런 워밍업 클럽 스터디 4기 - DevOps (쿠버네티스)를 진행하며 깊게 고민해 보려고 한 내용을 담습니다. 개괄적 정리보다 아는 것과의 비교를 통한 이해를 추구합니다. 또 Jenkins 파이프라인이 실패했다. 빌드는 성공했는데 배포 단계에서 타임아웃. kubectl로 수동 배포를 시도하니 이번엔 yaml 문법 에러다. 그런데 오늘부터 우리(?) 집에는 문어가 산다. 이 문어는 상당히 똑똑해서, 우리가 작업하고 싶어하는 배포들을 보다 단순하게 처리할 수 있도록 해 줄 것이다. 우리의 Jenkins가 못해먹겠다는 일을, 조금 더 덜어 보러 가 보자. ArgoCD? 우리의 문어, ArgoCD는 쿠버네티스 환경에서 GitOps 방식으로 애플리케이션을 배포해주는 도구다.Git 저장소를 지속적으로 모니터링하다가 변경사항이 생기면 자동으로 쿠버네티스에 배포해준다. 왜 ArgoCD일까? 궁금해서 찾아 보았더니. 그리스 신화에서 이아손과 아르고 선원들이 황금양털을 찾으러 탔던 배가 '아르고호(Argo)'란다. 험난한 바다를 항해해서 목적지에 도달하는 것처럼, ArgoCD도 복잡한 배포 과정을 자동으로 항해해서 원하는 상태로 애플리케이션을 배포해준다는 의미인 것 같다. Git이라는 나침반만 있으면 알아서 목적지까지 데려다준다니, 나름 꽤 적절한 네이밍 아닌가. 배포 진화의 4단계 강사님이 정리해주신 배포 레벨별 진화 과정이 명확했다. Level 1: Jenkins UI에서 클릭 몇 번으로 해결. 편하지만 파이프라인 설정이 UI에만 저장되어 변경 이력 추적이 안 된다.Level 2: Jenkinsfile로 파이프라인을 코드화. 이제 Git으로 관리할 수 있다. 하지만 여전히 Jenkins가 kubectl을 실행해서 직접 배포한다.Level 3: Helm이나 Kustomize로 YAML 템플릿화. 개발/스테이징/운영 환경별로 다른 설정을 쉽게 관리할 수 있다. 그래도 배포 트리거는 수동이다.Level 4: ArgoCD로 GitOps 완성. Git 변경 → 자동 배포, Blue/Green이나 Canary 같은 고급 배포 전략도 지원. 중요한 건 Level 3까지도 충분히 서비스 운영이 가능하다는 점이다. ArgoCD는 더 나은 선택지지, 반드시 필요한 건 아니다. 하지만 나는 ArgoCD를 도입해야만 한다. 사실 내가 할 건 아니다. 회사에서 쓰고 있다. 그럼 알아야지. (ㅋㅋ ㅠㅠ) Git이 진실의 원천이 되는 순간 이전 버전에서 알려주신 바로는 Jenkins에서 모든 걸 처리했다. 소스 빌드, 이미지 생성, 쿠버네티스 배포까지. 그런데 ArgoCD 아키텍처를 보니 접근 방식이 완전히 달랐다. Repo Server가 3분마다 Git 저장소를 확인한다. YAML 파일이 바뀌었나? 새로운 커밋이 있나?Application Controller가 현재 쿠버네티스 상태를 읽어온다. 그리고 Git의 내용과 비교한다.다르면? 자동으로 동기화한다. 이게 핵심이었다. Jenkins는 "배포하라"고 명령하는 방식이라면,ArgoCD는 "현재 상태가 원하는 상태와 같은가?"를 지속적으로 확인하는 방식이다. 일종의 Polling이지만, 권한을 더 이상 신경쓰지 않아도 된다는 의존 관계 해소가 가능하다.결과적으로 이제 Jenkins에서는 kubectl 권한을 관리할 필요가 없어진다.Pod에 대한 다른 모니터링 관리 툴 필요성도 줄어든다. 보안 측면에서도 좋고, 역할 분리도 명확해진다. 그런데 가장 흥미로웠던 건 Image Updater였다. Image Updater, 드디어 찾은 진짜 자동화? 기존에는 이랬다. 개발자가 코드 푸시Jenkins가 빌드하고 이미지 생성Jenkins가 YAML 파일의 이미지 태그를 수정하는 스크립트 실행수정된 YAML을 Git에 푸시ArgoCD가 변경사항 감지해서 배포 이제 Image Updater를 쓰면. 개발자가 코드 푸시Jenkins가 빌드하고 이미지를 Docker Hub에 업로드Image Updater가 새 이미지 감지자동으로 Git의 YAML 파일 수정ArgoCD가 변경사항 감지해서 배포 개발자는 코드만 푸시하면 끝이다. Jenkins 파이프라인에서 복잡한 YAML 수정 로직을 짤 필요가 없다. 단, 제약이 있다. Helm이나 Kustomize로 배포해야만 동작한다. 내부적으로 --set image.tag 옵션을 사용하기 때문이다. update-strategy 설정도 중요하다. semver로 하면 버전 규칙에 맞는 최신 버전으로, latest로 하면 가장 최근 이미지로 업데이트된다. Sync Policy, 자동화의 양날의 검 Manual vs Auto Sync Auto Sync. 좋아 보이지만 너무 무서운 단어가 아닌가? 난 서버에서 자동은 늘 무섭다.(;; 물론 요즘 선배님들의 자동화는 나의 매뉴얼보다 훨씬 낫다고 생각하지만..) 그래도 역시 강사님 설명을 들으니 함정이 있었다.Auto Sync + Self Heal 조합을 켜두면, 쿠버네티스에서 직접 수정한 내용이 모두 무시된다.HPA로 replica가 늘어나도 Git에 정의된 숫자로 다시 줄어든다. Sync Options Sync Options에서도 유사한 상황이 발생할 수 있다. AUTO-CREATE-NAMESPACE: 편리하지만 오타로 잘못된 네임스페이스가 생성될 수도 있다PRUNE RESOURCES: Git에서 삭제된 리소스를 쿠버네티스에서도 삭제하는데, 실수로 파일을 지웠을 때 운영 중인 서비스가 날아갈 수 있다 결국 환경별로 다르게 설정해야 한다. 개발 환경에서는 Auto Sync로 빠른 피드백을, 운영 환경에서는 Manual Sync로 안정성을 택하는 식으로. 오, 어쩐지 H2 같다. 정확한 타입 제한은 운영 DB에서만 처리할 때도 있으니까. 컴포넌트들의 역할 분담 이제 우리 집 문어를 뜯어 보자. ArgoCD 아키텍처를 보면 각 컴포넌트가 명확한 역할을 가지고 있다. Server: Web UI와 API 제공. 우리가 보는 대시보드가 여기서 나온다.Repo Server: Git 저장소와 소통. YAML 파일을 다운받아서 실제 배포할 매니페스트로 변환한다.Application Controller: 핵심 로직. 쿠버네티스 현재 상태와 Git의 desired state를 비교해서 동기화를 결정한다.Dex: SSO 연동. 회사에서 쓰는 LDAP이나 OAuth 프로바이더와 연결할 수 있다.Redis: 캐시 역할. Git과 쿠버네티스 API 호출을 줄여서 성능을 향상시킨다.Notification: 배포 결과를 Slack이나 이메일로 알려준다. 특히 ApplicationSet Controller가 인상적이었다. 개발/스테이징/운영 환경을 각각 다른 ArgoCD Application으로 만들 필요 없이, 하나의 템플릿으로 여러 환경을 관리할 수 있다고 해서. Directory vs Helm vs Kustomize ArgoCD에서 지원하는 세 가지 배포 방식. Directory 방식그냥 YAML 파일들을 kubectl apply 하는 것과 같다가장 간단하고 직관적이다하지만 Image Updater를 쓸 수 없다. 이미지 태그를 동적으로 바꿀 방법이 없기 때문이다 Helm 방식:values.yaml에서 환경별 설정을 관리한다Image Updater가 values.yaml의 이미지 태그를 자동으로 수정해준다템플릿 문법이 복잡할 수 있지만, 기능이 가장 풍부하다 Kustomize 방식base 디렉토리에 공통 설정, overlay 디렉토리에 환경별 차이점을 둔다Helm보다 가볍고 배우기 쉽다Image Updater도 지원하지만 Helm만큼 유연하지는 않다 결론적으로, 단순한 서비스라면 Directory도 충분하다.하지만 Image Updater로 자동화를 원하거나 멀티 환경 관리가 필요하다면 Helm이나 Kustomize를 써야 한다. 하지만 우리는 직전 강의에서 Helm의 태깅과 다양성이 필요하다는 이야기를 들었다. 간단한 프로젝트에서는 Kustomize이 괜찮겠지만, 어쩐지 Kustomize를 사용할 프로젝트에서 k8s를 사용하는 것은 오버엔지니어링일지도 모른다는 생각이 들기도 한다. 유사한 관점은 ArgoCD에서도 이어진다. 그래서, 정말 필요한가? Level 3으로도 충분히 잘 돌아가는 환경이라면 굳이 ArgoCD를 도입할 필요가 있을까? 강사님 말씀처럼 "유지보수 부담"도 생긴다. ArgoCD 자체도 쿠버네티스 위에서 돌아가는 애플리케이션이니까. 하지만 다음과 같은 상황이라면 도입을 고려해볼 만하다. Blue/Green, Canary 배포가 필요한 서비스멀티 클러스터 환경 관리Image Updater로 완전 자동화를 원하는 경우배포 과정에서 사람의 개입을 최소화하고 싶은 경우Git 기반으로 모든 배포 히스토리를 추적하고 싶은 경우 결국 '현재 내 상황에서 어떤 문제를 해결하고 싶은가'가 기준이 되어야 한다. Spring Boot 환경에서는 특히 Image Updater의 장점이 클 것이다.코드 변경 → 자동 빌드 → 자동 배포까지 완전히 세팅을 통해 자동화할 수 있으니까. 마무리하며 "나 이제... ArgoCD 쓸 수 있냐?" 음, 편리해졌다. 동시에 복잡성도 조금은 생긴다. Git에 푸시하면 알아서 배포되고, UI 대시보드에서 상태를 실시간으로 확인할 수 있고, 문제가 생기면 이전 버전으로 쉽게 롤백할 수 있다. 하지만 쉬워진 만큼 더 신중해져야 할 부분도 있다. Sync Policy 설정, Image Updater 전략, 멀티 클러스터 관리 등. 결국 도구는 도구일 뿐이고, 어떻게 쓰느냐가 중요하다. 그래도 한 가지는 확실하다. GitOps라는 개념을 제대로 구현해보고 싶다면, ArgoCD만큼 완성도 높은 도구는 찾기 어려울 것 같다. 이번에 강의를 마무리하면서 적용 시점이 다가오고 있어서 회사에서 다시금 ArgoCD를 접속했는데, 권한이 빠졌는지 대시보드가 뜨지 않고 회색 창이 떴다. SSO가 LDAP에서 키클락으로 바뀌어서 그럴 거라고 생각했다. 강의에도 그 부분이 나왔었다. 그리고 GitLab에 아키 팀이 설정해 둔 Helm 세팅에 대한 옵션을 봤다. 원래는 Helm이 무슨 역할을 하는지도 정확하게 알지 못해, 분명히 위키와 옵션을 봤음에도 기억하지 못했었다. 이제 옵션을 이해할 수 있다. 왜 이걸 쓰는지 알고 있다. 나는 이제 제법 K8S를 겁내지 않을 수 있겠구나. 4주 간의 여정을 즐겁게 마무리하면서, 앞으로의 Sprint 3에 대한 욕심도 생기고 있다. 멀게만 느껴졌던 DevOps, 이번 인프런 워밍업 클럽을 토대로 조금 더 가까워진 것 같다.