GitOps는 "환경이 어떤 상태여야 하는가"를 전부 git 저장소에 선언해 두고, git에 적힌 것을 유일한 진실(single source of truth)로 삼아 실제 환경을 맞추는 운영 방식이다. 서버에 직접 손대지 않고, 바꾸고 싶으면 git을 고친다.
풀려는 문제: 설정 드리프트
누군가 서버에 SSH로 들어가 컨테이너를 직접 띄우고, 설정 파일을 그 자리에서 고친다. 한 달 뒤엔 "지금 운영에 무슨 버전이 어떤 설정으로 떠 있지?"에 아무도 답하지 못한다. 실제 상태가 기록과 조금씩 어긋나는 이 현상을 설정 드리프트(configuration drift)라고 한다. 데이터베이스에서는 스키마 드리프트가 같은 문제다.
핵심 아이디어
- 선언형: "catalog를 띄우고 그다음 display를…"이 아니라 "catalog는 1.2.3, display는 1.0.1이어야 한다"를 적는다(선언형과 명령형 프로그래밍)
- git이 진실: 모든 변경이 커밋이므로 누가·언제·왜 바꿨는지 남고, PR로 리뷰할 수 있으며,
git revert가 곧 롤백이다 - 재현성: 같은 저장소를 적용하면 같은 환경이 다른 곳에도 생긴다
본격적인 GitOps
ArgoCD·Flux 같은 도구는 클러스터 안에서 git을 계속 감시한다.
- git이 바뀌면 자동으로 클러스터에 반영한다(pull 방식, pull-based deployment). CI가 클러스터 자격 증명을 들고 밀어 넣지 않아도 된다
- 누가 클러스터를 손으로 바꾸면 git 상태로 되돌린다(self-healing)
- 쿠버네티스 핵심 개념의 재조정 루프를 "git ↔ 클러스터" 수준으로 한 번 더 감싼 셈이다
CI는 이미지를 빌드해 레지스트리에 올리고 배포 저장소의 이미지 태그만 갱신하는 커밋을 남긴다(GitLab CI/CD 파이프라인). 꼭 자동 동기화까지 가지 않아도, 운영 매니페스트를 읽어 로컬 Docker Compose 설정을 생성하는 것처럼 "버전의 진실은 git에서 가져온다"는 원칙만 빌려 써도 효과가 크다.
flowchart TD
G["앱 저장소에 커밋"] --> CI["CI: 이미지 빌드"]
CI --> Reg[("레지스트리에 푸시")]
CI --> Tag["배포 저장소: 이미지 태그 갱신 커밋"]
Tag -- "감시·pull" --> Argo["ArgoCD·Flux"]
Argo -- "동기화" --> K["클러스터"]
Argo -. "손으로 바꾸면 git 상태로 되돌림 (self-healing)" .-> K
출처: OpenGitOps 원칙