GitOps는 DevOps 업계에서 꾸준히 주목받는 키워드입니다. GitOps란, 애플리케이션 코드부터 인프라 구성까지 필요한 모든 정보를 Git 저장소에 저장하고 관리하는 방법론인데요.
최근까지 GitOps 안에서도 다양한 개념과 용어가 정립되고 있다보니, 이를 알기 쉽게 정리하면 여러분들께 도움이 될 것 같아서 GitOps의 필수 개념들을 컴팩트하게 정리해보겠습니다.
이번 아티클에서는 실질적으로 도움이 되는 GitOps 관련 정보를 체계적으로 전달해드리기 위해 CNCF 재단 공인 GitOps 자격증 Certified GitOps Associate (CGOA)의 커리큘럼을 참고해서 구성했는데요. 해당 자격증을 준비하고 계신 분들에게도 유용하겠죠?
아래와 같이 GitOps 관련 5가지 소주제에 대해 알기 쉽게 풀어서 정리했으니, 이번 아티클을 끝까지 읽으시면 GitOps에 대해 탄탄한 기반 지식을 얻어가실 수 있을 겁니다.
- GitOps의 핵심 원칙
- GitOps 관련 용어
- GitOps 배포 패턴
- GitOps 관련 방법론
- GitOps 관련 도구
GitOps의 핵심 원칙
GitOps에 대해 이해하기 위해선 가장 먼저 GitOps의 핵심 원칙 4가지를 짚고 넘어가야 합니다.
1. 선언적(Declarative) 관리
GitOps의 첫 번째 주요 원칙은 시스템의 최종 상태를 소스코드로, 달리 말하자면 선언적(Declarative)으로 정의하는 것입니다. 시스템이 ‘어떻게’ 원하는 상태로 도달할지를 기술하는 절차적(Procedural) 방식과 달리, ‘어떤’ 상태가 되어야 하는지를 명시하는 방식을 말하는데요.
우리에게 익숙한 Kubernetes의 리소스를 정의한 YAML 파일이 이런 선언적 접근 방식의 대표적인 예시라고 할 수 있습니다. GitOps는 이렇게 선언된 최종 목표 상태를 기준으로 시스템을 관리하는 것이고요.
2. 버전 관리
다음 주요 원칙은 버전 관리입니다. GitOps에서 클러스터가 되어야 하는 최종 목표 상태(또는 사용자가 원하는 상태라고 해서 Desired State라고 합니다.)에 대한 모든 정보는 Git 저장소에 저장 및 관리됩니다.
즉, 사용자가 정의하는 클러스터의 최종 상태는 오직 Git 저장소에서만 저장되고 변경된다는 뜻인데요. 이를 설계 이론에서 사용하는 전문적인 말로 바꿔 말하면, ‘Git이 단일 진실 공급원(Single Source of Truth, SSoT)의 역할을 수행한다’고 말합니다. 시스템이 참조할 수 있는 진짜 정보는 오직 Git 한 곳에서만 관리한다는 의미입니다.
그리고 이런 Desired State는 Git 히스토리에 커밋 메시지와 함께 각 버전이 기록되는데요. 그 덕에 특정 상태가 언제, 왜, 어떻게 변경되었는지 추적하고 관리하기 쉽습니다. 만약 수정 후 문제가 발생해도 이전 상태로 안전하게 롤백(Rollback)하기도 용이하죠.
3. Pull 방식 자동화
Pull 방식 자동화란 전통적인 지속적 배포(CD)의 업데이트 방식과 GitOps의 업데이트 방식은 다르다는 것에서 출발합니다.
우리가 이미 알고 있는 CD 파이프라인은 클러스터로 변경 사항을 밀어넣는(Push) 방식인데요. GitOps는 이와 반대로, 클러스터 내부에 설치된 Argo CD나 Flux와 같은 에이전트가 Git 저장소로부터 클러스터의 최신 상태를 당겨오는(Pull) 방식입니다. 이건 기존의 DevOps 방식과 확연히 차이가 있기 때문에 Pull 방식 자동화가 GitOps의 주요 원칙이라 불리는 것입니다.
게다가 Pull 방식은 클러스터 외부에 위치한 시스템(예: CD 파이프라인)에 클러스터 접근 권한을 부여할 필요가 없기 때문에 잠재적인 보안 위험도 감소합니다. 클러스터의 경계를 더욱 명확하게 하고, 공격 표면을 줄이는 효과가 있는 것이죠.
4. 지속적 조정(Continuously Reconciled)
GitOps의 마지막 핵심 원칙인 지속적 조정은, 클러스터의 실제 상태(Actual State)가 Git에 저장된 최종 목표 상태(Desired State)와 일치할 때까지 끊임없이 조정(Reconcile)하는 것을 말합니다.
클러스터 내의 Argo CD나 Flux와 같은 GitOps 에이전트가 이 두 상태를 계속 비교하다가 만약 불일치(나중에 언급하겠지만, 이런 상태 불일치를 State Drift라고 합니다.)가 발생하면 이를 감지하고, 자동으로 조정하기도 하죠.
지속적으로 조정을 반복하는 과정은 클러스터의 일관성과 안정성을 보장하는 핵심 메커니즘입니다.
GitOps 관련 용어
위에서 GitOps의 핵심 원칙을 설명하는 과정에서 아마 익숙하지 않은 용어를 만나셨을 수도 있는데요. 그래서 GitOps에서 꼭 알아야 하는 핵심 용어 4가지를 짚고 넘어가겠습니다.
1. Desired State
(출처: https://control-plane.io/posts/what-is-gitops/)
클러스터의 Desired State란, 개발자 또는 관리자가 최종 목표로 정의한 상태를 말합니다. 특히 GitOps에선 Git 저장소에 코드로 정의된 최종 목표 상태를 의미하죠.
Git 저장소에서 관리되기 때문에 Desired State의 변경 이력도 당연히 관리와 추적이 가능합니다.
GitOps의 모든 활동은 클러스터의 실제 상태(Actual State)를 Desired State와 일치시키는 것을 목표로 합니다.
2. State Drift
(출처: https://openliberty.io/blog/2024/04/26/argocd-drift-pt1.html)
State Drift(상태 드리프트)는 Git 저장소에 선언된 Desired State와 현재 클러스터의 실제 상태가 일치하지 않는 현상을 말합니다. 관리자에 의한 코드 수동 변경이나 설정 오류, 예기치 못한 장애 등 다양한 원인으로 State Drift가 발생할 수 있는데요.
Argo CD나 Flux 같은 GitOps 에이전트는 이런 Drift를 지속적으로 감지하고, 수정하거나 사용자에게 경고 알림을 보내는 역할을 수행합니다.
3. Feedback Loop
GitOps의 마지막 핵심 원칙에서도 언급했던 ‘조정(Reconcile)의 반복’은 Feedback Loop라는 개념을 실제로 구현한 것입니다.
Feedback Loop란 지속적으로 클러스터의 실제 상태를 측정하고, 이를 Desired State와 비교하여 그 차이를 줄이는 방향으로 클러스터를 제어하는 것을 의미합니다. 외부의 변화나 내부의 오류가 발생하더라도 클러스터가 안정적인 상태를 유지할 수 있도록 하는 것이죠.
4. Rollback
클러스터에 문제가 발생하여 이전 상태로 되돌려야 할 때, GitOps는 아주 효과적으로 Rollback할 수 있습니다.
Desired State가 Git에서 관리되므로, git revert
나 상황에 따라서는 git reset
명령어로 이전 커밋을 가리키도록 변경하는 것이 어렵지 않기 때문인데요.
이렇게 Rollback되면 GitOps 에이전트가 그 변경을 감지하여 클러스터를 해당 버전으로 자동 복구하므로 빠르고 안정적인 장애 복구가 가능합니다.
GitOps 배포 패턴
GitOps 방법론에서 사용할 수 있는 배포 패턴은 다양한데요. 그 중에서도 GitOps의 핵심 배포 패턴 4가지를 컴팩트하게 살펴보겠습니다.
1. 배포 및 릴리즈 패턴
-
환경별 브랜치 패턴
- 개발(
dev
), 스테이징(staging
), 운영(prod
) 등 각 배포 환경에 해당하는 별도의 Git 브랜치를 운영하는 방식입니다. - 변경 사항은 대개 Pull Request를 통해
dev
에서staging
으로, 다시staging
에서prod
순서로 병합됩니다. - 각 환경의 상태를 명확하게 격리하고 관리할 수 있는 것이 장점입니다.
- 개발(
-
환경별 디렉토리 패턴
- 여러 브랜치를 사용하지 않고, 단일
main
브랜치 내에서overlays/dev
,overlays/prod
와 같이 각 환경에 해당하는 디렉토리를 만들어 설정을 관리하는 방식입니다. - Kustomize와 같은 도구를 사용하여 공통된 기본 설정에 각 환경별 변경 사항을 덧씌우는 방식으로 동작합니다.
- 브랜치 관리의 복잡성을 줄일 수 있는 것이 장점입니다.
- 여러 브랜치를 사용하지 않고, 단일
-
App of Apps 패턴
- 다수의 마이크로서비스나 애플리케이션을 배포하고 관리해야 할 때 유용히 사용되는 패턴입니다.
- 여러 개의 하위 애플리케이션들을 관리하는 하나의 상위 애플리케이션을 두는 방식입니다.
- Agro CD와 같은 도구에서 주로 사용되며, 복잡한 시스템의 배포를 중앙에서 일관되게 관리할 수 있는 것이 장점입니다.
(출처: https://blog.devops.dev/app-of-apps-and-ignoredifferences-in-argo-cd-dcb1f2392561)
2. 점진적 배포(Progressive Delivery) 패턴
-
카나리 배포 패턴
- 새로운 애플리케이션 버전을 일부 사용자에게만 먼저 배포하는 방식입니다.
- Git 저장소의 매니페스트 파일에서 트래픽 가중치(예:
stable: 90%
,canary: 10%
)를 변경하는 식으로 구현할 수 있습니다. - 새 버전의 안정성을 실제 트래픽으로 검증하여 위험을 최소화할 수 있는 것이 장점입니다.
-
Blue/Green 배포 패턴
- 현재 운영 중인 버전(Blue)과 동일한 환경에 새로운 버전(Green)을 배포한 후, 트래픽을 한 번에 전환하는 방식입니다.
- GitOps 환경에서는 Git의 매니페스트를 수정하여 트래픽 라우팅 대상을 Green 버전으로 변경함으로써 구현할 수 있습니다.
- 문제가 발생하면 즉시 트래픽을 다시 Blue 버전으로 되돌릴 수도 있기 때문에, 다운타임 없는 안전한 배포가 가능하다는 것이 장점입니다.
3. Pull vs Event-driven
우리가 위에서 살펴본 Pull 방식은 정해진 주기마다 Git 저장소 내 매니페스트의 변경 사항을 확인합니다. 반면에 Event-driven 방식은 특정 이벤트가 발생했을 때 동기화를 시작합니다.
예를 들어 Git 저장소에 새로운 커밋이 푸시되거나 이미지 레지스트리에 새버전의 이미지가 등록되면, Webhook 등을 통해 GitOps 에이전트가 이러한 변경 사항을 인지할 수 있게 되는 것이죠.
그래서 Event-driven 방식이 보다 더 빠른 피드백과 신속한 배포가 가능합니다.
4. 아키텍처 패턴
GitOps 아키텍처에서는 애플리케이션 소스코드를 담는 저장소와, 해당 애플리케이션의 배포 방법을 정의한 k8s 매니페스트를 담는 저장소를 분리하여 관리하는 것이 권장됩니다.
이 방식은 관심사의 분리(Seperation of Concerns)라는 원칙에 따라, 개발팀은 애플리케이션 코드에 집중하고 운영팀은 배포와 운영에 집중할 수 있도록 도와주는데요.
거기에 매니페스트 저장소에 대한 접근 권한은 더욱 엄격히 관리할 수 있어 클러스터 보안에도 유리합니다.
GitOps 관련 방법론
이 시점에서 GitOps와 깊이 연관된 다른 방법론을 함께 보면 GitOps에 대해 더 효과적으로 이해할 수 있습니다. 그래서 이번엔 GitOps 관련 주요 방법론 4가지를 알아보겠습니다.
1. Configuration as Code (CaC)
CaC는 인프라나 애플리케이션의 구성을 스크립트나 소스코드 파일로 관리하는 방법론입니다. GitOps는 Kubernetes 매니페스트 YAML 파일을 사용하여 애플리케이션의 구성을 코드로 명확하게 정의하고, Git으로 버전 관리하여 CaC를 실현할 수 있는데요.
GitOps와 CaC를 결합하면 애플리케이션의 배포 버전부터 리소스 요구량, 환경 변수 등 다양한 구성의 업데이트가 Git 커밋으로 남기 때문에, 변경 사항을 투명하게 추적하고 검토할 수 있어 클러스터를 안정적으로 운영할 수 있습니다.
2. Infrastructure as Code (IaC)
VM이나 네트워크와 같은 인프라를 코드로 관리하는 방법론인 IaC 역시 GitOps에서 손쉽게 실현될 수 있습니다.
Terraform이나 Pulumi와 같은 IaC 도구로 생성한 인프라 코드를 Git 저장소에 저장하고 관리하면서 변경 이력을 추적할 수 있다면, 인프라 코드도 더욱 안정적으로 개발하고 관리할 수 있겠죠?
그래서 GitOps와 IaC는 함께 활용되는 경우가 많습니다.
3. DevOps 및 DevSecOps
GitOps는 개발자가 Git 저장소에 코드를 Push하는 것만으로 배포에 참여할 수 있고, 클러스터 운영자는 Git을 통해 모든 배포 상태를 명확히 파악할 수 있기 때문에 팀 간의 협업에도 유리합니다. 결국 GitOps는 DevOps를 Git 기반으로 구현한 방법론이라고 할 수 있죠.
또한, 정적 분석이나 취약점 스캔과 같은 보안 검사도 Git Pull Request 기반의 자동화 파이프라인에 포함되기 용이합니다. Git 저장소의 접근 제어와 브랜치 보호 규칙 등은 누가 클러스터 구성요소를 변경할 수 있는지를 엄격히 통제할 수도 있고요. 그래서 GitOps는 개발 초기 단계부터 보안을 고려하는 DevSecOps 문화를 실현하는 것도 가능합니다.
4. 지속적 통합(CI)과 지속적 배포(CD)
GitOps에서의 CI와 CD에 대해 이야기해보겠습니다.
GitOps 워크플로우에서 CI 파이프라인의 주요 역할은 애플리케이션 소스코드 빌드부터 단위 테스트/통합 테스트, 그리고 애플리케이션 구성을 배포 가능한 이미지로 만들어 이미지 저장소에 Push하는 것까지입니다. 이렇게 GitOps에서의 CI의 책임은 명확히 구분할 수 있는데요. 바꿔 말하자면, CI 파이프라인이 애플리케이션을 클러스터에 직접 배포하진 않습니다.
GitOps에서 Continuous Deployment(CD)의 역할은 클러스터 내에서 실행되는 GitOps 에이전트가 담당합니다. 예를 들어, 개발자가 Git 저장소에서 관리되는 Kubernetes 매니페스트를 업데이트할 경우, GitOps 에이전트가 해당 변경을 감지해서 새로운 Kubernetes 리소스를 클러스터에 배포하는 거죠.
이렇게 GitOps에서 외부 CI 파이프라인은 클러스터에 접근할 필요가 없기 때문에, 클러스터 내부로 침투할 수 있는 표면을 줄여 보안 측면에서 유리해집니다.
GitOps 관련 도구
여기까지 오시느라 고생 많으셨습니다. 이번 아티클의 마지막 섹션으로, GitOps 관련 도구들을 살펴보겠습니다. 아마 낯익은 도구들도 만나실 거예요.
매니페스트 포매팅(Formatting) 및 패키징(Packaging)
포매팅이라 함은 파일의 내용을 원하는 형식으로 바꾸는 걸 말합니다. 매니페스트 포매팅이라고 하면 매티페스트 파일의 내용을 사용자가 원하는 형식으로 변환시키는 작업을 의미하죠.
각 환경마다 Kubernetes 매니페스트 YAML 파일의 내용을 변경해야 할 경우, 일일이 환경이 바뀔 때마다 직접 매니페스트 파일을 수정하는 건 손이 많이 가고 실수가 발생하기도 쉬운데요. 이런 문제를 해결하기 위해 등장한 매니페스트 포매팅 툴이 있습니다. 대표적으로 Kustomize가 있죠.
Kustomize는 Base가 되는 YAML 파일을 dev
, staging
, prod
와 같은 각기 다른 환경에 맞춰 매니페스트 내용을 변경해 배포할 수 있도록 도와줍니다. Kustomize는 이미 지난번에 다룬 적이 있는데요, 만약 Kustomize의 핵심 컨셉과 실습 가이드가 궁금하시다면 minikube 환경에서 따라해보는 Kustomize 실습 아티클에서 확인해보세요.
Kubernetes 클러스터에 배포하는 애플리케이션은 다양한 Kubernetes 리소스로 구성되는 경우가 많습니다. 이런 애플리케이션을 다른 클러스터에 배포하기 위해 공유해야 한다면, 구성 리소스에 대한 매니페스트 YAML 파일을 직접 옮겨야 할까요? 그럴 수도 있겠지만, 매니페스트 파일들을 하나의 단위로 묶어서 공유할 수 있다면 더 편리하지 않을까요? 이런 문제 의식에서 등장한 것이 바로 매니페스트 패키징이고, 대표적인 툴로 Helm이 있습니다.
Helm은 Kubernetes 패키지 매니저라고도 하는데요. 우리가 Python으로 개발할 때 라이브러리 설치 용도로 사용하는 Pip처럼, Helm은 원격에 저장된 Kubernetes 애플리케이션을 손쉽게 다운로드받고 클러스터에 배포할 수 있도록 도와줍니다.
Helm으로 공유되는 Kubernetes 애플리케이션의 리소스 매니페스트 파일들의 내용은 고정되어 있지 않고 특정 값을 넣을 수 있도록 템플릿화되어 있기 때문에, 동일한 애플리케이션이라고 해도 클러스터나 환경에 따라 다른 설정으로 쉽게 배포할 수 있는 것이 장점입니다.
GitOps 워크플로우에서는 Kustomize와 Helm이 참조하는 클러스터/환경 전용 설정 값들을 Git에 저장하고 관리함으로써 변경 이력 기록 및 추적을 용이하게 만들 수 있습니다.
State Store 시스템
클러스터의 Desired State를 저장하고 관리하는 핵심 시스템을 State Store라고 하는데요. 아마 눈치채셨겠지만, GitOps에서 State Store는 Git 저장소입니다.
변경 이력 추적이나 Pull Request를 통한 협업이 가능하기 때문에 Git은 State Store로 손색이 없습니다. 별도의 데이터베이스나 상태 관리 시스템도 필요하지 않기 때문에 직관적으로 사용 가능하다는 것도 장점입니다.
조정 엔진(Reconciliation Engine)
GitOps의 핵심 요소라 할 수 있는 조정 엔진은 Argo CD와 Flux가 대표적입니다.
Argo CD는 직관적인 웹 UI를 통해 애플리케이션의 배포 상태와 동기화 상태, 리소스 관계 등을 한 눈에 파악할 수 있고, 여러 Kubernetes 클러스터를 중앙에서 관리하는 기능도 제공합니다. GitOps 배포 패턴에서 살펴봤던 App of Apps 패턴도 지원합니다.
(출처: https://argo-cd.readthedocs.io/en/latest/operator-manual/cluster-bootstrapping/)
Flux는 GitOps Toolkit이라는 독립된 컴포넌트들의 집합으로 구성되어 있습니다. 사용자가 GitOps 도입에 필요한 기능만 선택해서 설치할 수 있어서 유연하다는 것이 특징인데요.
주로 터미널 환경에서 Kubernetes 클러스터를 관리하며, Kubernetes 생태계와 긴밀한 통합을 지향하는 툴입니다. Argo CD에 비해 좀 더 미니멀한 접근 방식을 선호하는 사용자에게 적합한 툴입니다.
(출처: https://fluxcd.io/flux/components/)
알림 도구를 활용한 상호운용성(Interoperability with Notification)
대부분의 GitOps 도구는 Slack이나 Microsoft Teams, 이메일 같은 다양한 알림 채널과 연동하는 기능을 제공하고 있습니다. 그래서 애플리케이션 배포 성공이나 State Drift 감지, 동기화 실패 같은 이벤트가 발생하면 담당자에게 실시간으로 알릴 수 있는 거죠.
이런 알림 도구를 활용한 상호운용성 덕분에 팀은 클러스터의 상태를 신속하게 인지하고 필요한 조치를 취할 수 있게 됩니다.
마무리
점점 복잡해지고 고도화되는 클라우드 환경에서 GitOps는 유지보수성과 체계성을 모두 갖추고자 하는 개발자들에게 좋은 모범 사례가 되고 있습니다. 그래서 여러분들께 소개해드리면 앞으로 클러스터 배포와 관련된 의사결정이 필요할 때 도움이 되겠다는 생각이 들었습니다.
그래서 이렇게 GitOps를 이해하는 데에 필수적인 개념과 용어들을 총정리해봤는데요. 이번 기회에 GitOps에 대해 감을 확실하게 잡으셨길 바랍니다.
만약 본 아티클을 읽고 GitOps에 대해 흥미가 더 생기셨다면 Argo CD와 Flux가 각각 GitOps를 어떤 방식으로 구현했는지 그 차이점을 알아보시는 걸 추천드립니다. GitOps에 대한 이론 지식을 넘어서 GitOps가 어떻게 쓰이는지 더 깊이 이해하시게 될 거예요.
그럼 다음 아티클에서 더 흥미로운 주제로 찾아오겠습니다. 감사합니다.