GitOps란 무엇인가 - 인프라를 코드로 관리하는 현대적 배포 방식 (ArgoCD)
1. "누가 운영 서버 건드렸어?"
개발팀에서 이런 대화는 너무나 흔합니다.
A: "어제까지만 해도 잘 돌아가던 서비스가 갑자기 500 에러를 뱉어요!"
B: "아, 제가 아까 급해서 운영 서버 들어가서 메모리 설정 좀 바꿨는데..."
A: "그거 어디 기록해뒀나요?"
B: "아뇨, 그냥 kubectl edit으로 바로 고쳤는데요..."
이게 바로 "구성 표류(Configuration Drift)"의 시작입니다.
서버의 실제 상태(Actual State)가 우리 모르게 조금씩 바뀌어서, 아무도 현재 서버가 정확히 어떤 설정인지 모르는 상태가 되는 것이죠.
이 문제를 해결하기 위해 등장한 개념이 바로 GitOps입니다.
핵심은 간단합니다. "Git에 있는 코드가 곧 서버의 상태다."
2. GitOps의 핵심 원칙 4가지
GitOps는 단순히 툴 이름이 아니라 방법론입니다. OpenGitOps에서 정의한 4가지 원칙이 있습니다.
- 선언적(Declarative): 시스템의 상태는 명령어가 아닌 선언형 코드(YAML 등)로 기술되어야 합니다. ("메모리를 늘려라"가 아니라 "메모리는 2GB다"라고 기술)
- 버전 관리 및 불변성(Versioned & Immutable): 모든 설정 파일은 Git에 저장되고 버전 관리되어야 합니다. 누가, 언제, 무엇을 바꿨는지 추적 가능해야 합니다.
- 자동 적용(Pulled Automatically): Git에 변경사항이 푸시되면, 자동으로 시스템에 적용되어야 합니다.
- 지속적 조정(Continuously Reconciled): 실제 상태가 Git에 정의된 상태와 달라지면(Drift), 시스템이 이를 감지하고 스스로 복구해야 합니다.
3. CIOps (Push) vs GitOps (Pull)
기존의 CI/CD 방식(CIOps)과 GitOps의 가장 큰 차이는 누가 배포를 주도하냐입니다.
기존 방식 (Push Type)
Jenkins나 GitHub Actions 같은 CI 툴이 "내가 가서 서버에 배포할게!" 하는 방식입니다.
- 보안 문제: CI 툴에게 운영 서버(K8s 클러스터)의 접근 권한(마스터 키)을 줘야 합니다. CI 툴이 해킹당하면 운영 서버도 털립니다.
- 상태 파악 불가: 배포 후 누군가 서버를 직접 수정하면 CI 툴은 그걸 모릅니다.
GitOps 방식 (Pull Type)
서버 안에 살고 있는 에이전트(ArgoCD, Flux)가 "Git 저장소에 뭐 바뀐 거 있나?" 하고 주기적으로 확인해서 가져오는 방식입니다.
- 보안 강화: 클러스터 외부에서 내부로 들어오는 권한을 줄 필요가 없습니다. 에이전트가 내부에서 밖(Git)을 보고 가져오기만 하니까요.
- Drift 감지: 누군가 몰래 서버를 수정해도, 에이전트가 "어? Git이랑 다르네?" 하고 감지해서 원상 복구 시킬 수 있습니다.
4. 실제 도구: ArgoCD
가장 대중적인 GitOps 도구는 ArgoCD입니다. Kubernetes 네이티브라서 설치도 쉽고 UI가 매우 훌륭합니다.
ArgoCD를 설정하면 다음과 같은 흐름이 만들어집니다.
- 개발자가
deployment.yaml의 이미지 태그를 v1.0에서 v1.1로 수정해서 Git에 푸시합니다.
- ArgoCD가 "어? Git은
v1.1인데, 지금 클러스터는 v1.0이네? OutOfSync 상태다!"라고 감지합니다.
- ArgoCD가 자동으로(또는 수동 승인 후) 클러스터 상태를
v1.1로 동기화(Sync) 합니다.
이 모든 과정이 시각화되어 보이고, 만약 배포가 잘못되면 Git에서 Revert 버튼 한 번만 누르면 ArgoCD가 즉시 이전 버전으로 롤백합니다. 배포와 롤백이 획기적으로 빨라지고 안전해집니다.
graph LR
Dev[개발자] -->|1. PR Merge| Git[Git Repository]
Argo[ArgoCD Agent] -->|2. 감시 (Polling)| Git
Argo -->|3. 동기화 (Sync)| K8s[Kubernetes Cluster]
style Git fill:#f9f,stroke:#333
style Argo fill:#9ff,stroke:#333
style K8s fill:#9f9,stroke:#333
ArgoCD는 3분마다 Git 저장소를 훔쳐봅니다.
"어? Git에는 replicas: 3인데, 지금 클러스터는 replicas: 1이네? 이상하다(Drift 감지)."
그리고 즉시 Git의 상태와 똑같이 맞춰줍니다(Sync).
5. 실제 도입 - Self-Healing의 기적
GitOps를 도입하고 겪은 가장 짜릿한 경험은 자동 치유(Self-Healing)였습니다.
어느 날 신입 개발자가 실수로 운영 서버의 중요한 데플로이먼트를 삭제했습니다.
# 앗... 실수로 삭제!
kubectl delete deployment my-payment-service
나는 비명을 지르며 복구 명령어를 찾고 있었는데, 1분 뒤 슬랙 알림이 왔습니다.
"Service is Healthy."
ArgoCD가 "어? Git 명세서에는 이 서비스가 있어야 하는데 실제로 가보니 없네? 내가 다시 만들어야겠다!"라고 판단하고, Git에 있는 설정대로 다시 생성해 버린 겁니다.
우리는 아무것도 안 했습니다. 그냥 ArgoCD가 열일한 거죠.
이제 우리 서버는 불사신이 되었습니다. 누가 와서 서버를 난장판으로 만들어도, ArgoCD가 Git을 보고 다시 원상 복구해 놓으니까요. 이것이 진정한 선언적(Declarative) 인프라입니다.
6. 도입 후 달라진 점
6.1 배포가 승인 프로세스가 됨
이전에는 누군가의 PC에서 비밀스럽게 배포가 일어났지만, 이제는 Pull Request(PR)가 곧 배포입니다.
"메모리 늘릴게요"라고 PR을 올리면, 리뷰어가 검토하고 승인(Merge)합니다. Merge 버튼을 누르면 그게 곧 배포 시작입니다.
배포 권한 같은 복잡한 관리 없이, Git 권한 관리로 통일되었습니다.
6.2 환경 분리 (Staging vs Production)
저희는 Kustomize를 사용해서 환경을 관리합니다.
base/에는 공통 설정을 두고, overlays/dev, overlays/prod에서 차이점(CPU, Memory, Replicas 등)만 관리합니다.
ArgoCD는 각 환경에 맞는 폴더를 바라보게 설정해 두면 끝입니다.
7. 도구 선택의 고민: Helm vs Kustomize, ArgoCD vs Flux
GitOps를 도입할 때 가장 큰 고민은 "어떤 도구를 쓸까?"였습니다.
7.1 Helm vs Kustomize
처음에는 Helm을 고려했습니다. Helm은 템플릿 방식이라 변수({{ .Values.image }})만 갈아 끼우면 되니 편해 보였습니다.
하지만 YAML 파일이 복잡해질수록 템플릿 문법이 난해해졌고, "렌더링 하기 전에는 결과를 알 수 없다"는 점이 불안했습니다.
반면 Kustomize는 순수한 YAML을 겹쳐서(Overlay) 패치하는 방식입니다.
- 장점: 원본 YAML을 그대로 유지하면서 필요한 부분만 수정 가능.
- 단점: 텍스트 중복이 좀 생길 수 있음.
저희 팀은 "직관성"을 위해 Kustomize를 선택했습니다. Git에 올라간 파일이 곧 최종 결과물이라는 철학에 더 잘 맞았기 때문입니다.
7.2 ArgoCD vs Flux
Flux CD도 훌륭하지만, 저희는 ArgoCD를 선택했습니다.
가장 큰 이유는 "예쁜 UI" 때문이었습니다.
ArgoCD는 현재 클러스터 상태를 시각적인 그래프로 보여줍니다. 개발자들이 터미널에서 kubectl을 치지 않아도, 웹 대시보드만 보면 "아, 지금 내 앱이 배포 중이구나", "Pod가 하나 죽었구나"를 직관적으로 알 수 있습니다. 이 시각화가 주는 심리적 안정감은 엄청났습니다.
8. 주의할 점
물론 GitOps가 만능은 아닙니다.
- 비밀값(Secret) 관리: 비밀번호나 API 키를 Git에 텍스트(Plain Text)로 올리면 큰일 납니다.
- 해결책: Sealed Secrets나 External Secrets Operator를 사용해서, Git에는 암호화된 값만 올리고 클러스터 내부에서 복호화해서 써야 합니다.
- CI와 CD의 분리: 코드를 빌드하는 것(CI)과 설정을 바꾸는 것(CD)을 명확히 분리해야 합니다.
- CI(GitHub Actions): 코드를 빌드하고 Docker 이미지를 만들어서 레지스트리에 푸시.
- CD(ArgoCD): Git의 이미지 태그 버전을 업데이트.
9. 한 줄 요약
GitOps는 "Git에 적힌 대로 서버를 만든다"는 약속이다. ArgoCD 같은 도구를 써서 이 약속을 자동으로 지키게 하면, 운영의 고통(Config Drift)이 사라지고 주말에도 꿀잠을 잘 수 있다.