GitOps Workflow 설계 가이드: Kubernetes와 CI/CD 자동화
GitOps의 핵심 원칙을 이해하고, Kubernetes 환경에서 CI/CD 파이프라인을 구축하는 실용적인 워크플로우 설계 가이드를 제공합니다. Docker, Argo CD 활용 예시 포함.
GitOps Workflow 설계 가이드: Kubernetes와 CI/CD 자동화
현대 소프트웨어 개발 환경에서 애플리케이션의 빠른 배포와 안정적인 운영은 핵심 경쟁력으로 자리 잡았습니다. 이러한 요구사항을 충족시키기 위해 DevOps 문화와 방법론이 확산되었으며, 그중 GitOps는 인프라 및 애플리케이션 배포를 자동화하고 관리하는 강력한 패러다임으로 주목받고 있습니다. 이 글에서는 GitOps의 기본 원칙부터 Kubernetes 환경에서 효율적인 CI/CD 워크플로우를 설계하는 실질적인 가이드라인을 제시하고, 구체적인 CLI 명령어 및 설정 파일 예시를 통해 GitOps 구현 방법을 심층적으로 다루겠습니다.
GitOps의 핵심 원칙 이해
GitOps는 Git을 "진실의 유일한 원천(Single Source of Truth)"으로 삼아 인프라와 애플리케이션의 상태를 관리하는 운영 모델입니다. 모든 변경 사항은 Git 저장소에 기록되며, 이 저장소의 상태가 실제 배포된 시스템의 상태와 일치하도록 보장하는 것을 목표로 합니다. GitOps를 구성하는 주요 원칙들은 다음과 같습니다.
1. 선언적(Declarative) 인프라 및 애플리케이션
GitOps는 Kubernetes Manifest, Helm Chart, Kustomize 설정 등 선언적인 방식으로 인프라와 애플리케이션의 원하는 상태를 정의합니다. 이는 "어떻게"가 아닌 "무엇을" 배포할 것인지에 집중하며, 시스템의 현재 상태를 쉽게 파악하고 예측 가능하게 만듭니다. 예를 들어, Kubernetes Deployment YAML 파일은 특정 컨테이너 이미지를 몇 개의 Pod으로 실행할 것인지를 명시합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-registry/my-app:v1.0.0
ports:
- containerPort: 8080
2. Git을 통한 버전 관리 및 변경 추적
모든 인프라 및 애플리케이션 설정은 Git 저장소에 저장되어 버전 관리가 됩니다. 이는 변경 이력을 투명하게 추적하고, 필요한 경우 언제든지 이전 상태로 롤백할 수 있게 합니다. 누가, 언제, 무엇을 변경했는지 명확하게 파악할 수 있으므로 감사(Audit)에도 용이합니다.
3. Pull 기반 자동화된 배포
기존 CI/CD 파이프라인은 CI 서버가 배포 대상 클러스터에 변경 사항을 "Push"하는 방식이 많았습니다. 반면 GitOps는 클러스터 내의 에이전트(예: Argo CD, Flux CD)가 Git 저장소의 변경 사항을 지속적으로 "Pull"하여 클러스터의 상태를 Git에 정의된 상태와 일치시킵니다. 이 방식은 클러스터 외부에서 클러스터로의 접근 권한을 최소화하여 보안을 강화합니다.
4. 지속적인 동기화 및 상태 일치 보장
GitOps 에이전트는 Git 저장소와 클러스터의 실제 상태를 지속적으로 비교하고, 불일치가 감지되면 자동으로 동기화하여 Git에 정의된 상태를 유지합니다. 이를 통해 수동적인 변경이나 외부 요인으로 인한 상태 변경을 즉시 감지하고 복구할 수 있습니다.
5. 관찰 가능성(Observability)
GitOps 도구들은 배포 상태, 동기화 진행 상황, 오류 발생 여부 등을 시각적으로 제공하여 시스템의 상태를 쉽게 모니터링할 수 있도록 돕습니다. 이를 통해 문제가 발생했을 때 신속하게 원인을 파악하고 대응할 수 있습니다.
GitOps 워크플로우의 주요 구성 요소
효율적인 GitOps 워크플로우를 설계하기 위해서는 몇 가지 핵심 구성 요소들을 이해하고 통합해야 합니다.
1. 버전 관리 시스템 (VCS): Git
Git은 GitOps의 핵심입니다. 모든 코드, 설정 파일, 인프라 Manifest가 Git 저장소에 관리됩니다. GitHub, GitLab, Bitbucket 등 다양한 Git 호스팅 서비스를 사용할 수 있습니다.
2. CI (Continuous Integration) 도구
애플리케이션 코드 변경이 감지되면 자동으로 빌드, 테스트, Docker 이미지 생성 및 컨테이너 레지스트리 푸시를 수행합니다. GitHub Actions, GitLab CI, Jenkins, CircleCI 등이 대표적입니다.
3. CD (Continuous Delivery/Deployment) 도구 (GitOps Operator)
Git 저장소에 정의된 원하는 상태와 클러스터의 실제 상태를 지속적으로 비교하고 동기화하는 역할을 합니다. Argo CD와 Flux CD가 GitOps의 대표적인 CD 도구입니다. 이들은 클러스터 내에서 동작하며 Git 변경 사항을 감지하고 Kubernetes API를 통해 리소스를 배포합니다.
4. Container Registry
빌드된 Docker 이미지를 저장하고 관리하는 중앙 저장소입니다. Docker Hub, Google Container Registry (GCR), Amazon Elastic Container Registry (ECR), Quay.io 등이 있습니다.
5. Kubernetes Cluster
애플리케이션이 배포되고 실행될 대상 환경입니다. 온프레미스 또는 클라우드 기반의 Kubernetes 클러스터(EKS, GKE, AKS 등)를 사용할 수 있습니다.
GitOps 저장소 구조 설계
GitOps의 성공적인 구현을 위해서는 Git 저장소 구조를 신중하게 설계하는 것이 중요합니다. 일반적으로 애플리케이션 코드와 Kubernetes Manifest를 별도의 저장소로 분리하는 전략이 많이 사용됩니다.
1. 애플리케이션 코드 저장소 (Application Repository)
- 애플리케이션 소스 코드, Dockerfile, CI 설정 파일 (
.github/workflows,.gitlab-ci.yml등)을 포함합니다. - 개발자는 이 저장소에 코드를 커밋하고 Pull Request를 생성합니다.
- CI 파이프라인은 이 저장소의 변경 사항을 감지하여 Docker 이미지를 빌드하고 Container Registry에 푸시합니다.
2. Kubernetes Manifest 저장소 (Infrastructure/Manifest Repository)
- Kubernetes Deployment, Service, Ingress 등 애플리케이션 배포에 필요한 모든 YAML Manifest 파일들을 포함합니다.
- Helm Chart, Kustomize 파일 등 환경별 설정을 관리하는 파일들도 이곳에 저장됩니다.
- CD 도구(Argo CD 등)는 이 저장소를 모니터링하며 클러스터의 상태를 동기화합니다.
예시: Manifest 저장소 구조
infra-repo/
├── apps/
│ ├── my-app/
│ │ ├── base/ # 공통 Kubernetes Manifest
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/ # 환경별 오버레이
│ │ ├── dev/
│ │ │ ├── kustomization.yaml
│ │ │ └── deployment-patch.yaml
│ │ └── prod/
│ │ ├── kustomization.yaml
│ │ └── deployment-patch.yaml
│ └── another-app/
│ └── ...
└── clusters/ # 클러스터별 Argo CD Application 정의
├── dev-cluster/
│ └── argocd-app-my-app.yaml
└── prod-cluster/
└── argocd-app-my-app.yaml
이 구조는 Kustomize를 활용하여 base 디렉토리에 공통 Manifest를 정의하고, overlays 디렉토리에서 개발(dev) 및 운영(prod) 환경별로 필요한 변경 사항(예: replica 수, 환경 변수)을 적용합니다.
CI 파이프라인 구축: Application Build & Push
GitOps 워크플로우의 첫 단계는 애플리케이션 코드 변경을 감지하고, 새로운 Docker 이미지를 빌드한 후 Container Registry에 푸시하는 CI 파이프라인을 구축하는 것입니다. 이 과정에서 가장 중요한 부분은 빌드된 이미지의 태그를 Kubernetes Manifest 저장소에 자동으로 업데이트하는 것입니다.
1. Dockerfile 작성
애플리케이션 코드 저장소에 Dockerfile을 작성하여 애플리케이션을 컨테이너 이미지로 빌드할 수 있도록 합니다.
# Dockerfile 예시
FROM node:18-alpine
WORKDIR /app
# 패키지 의존성 파일 복사 및 설치
COPY package*.json ./
RUN npm install
# 애플리케이션 소스 코드 복사
COPY . .
# 애플리케이션 시작 명령어
CMD ["npm", "start"]
# 컨테이너 포트 노출 (선택 사항)
EXPOSE 3000
2. CI 워크플로우 설정 (GitHub Actions 예시)
애플리케이션 코드 저장소에 .github/workflows/ci.yaml 파일을 생성하여 CI 파이프라인을 정의합니다. 이 워크플로우는 main 브랜치에 푸시가 발생할 때마다 실행됩니다.
# .github/workflows/ci.yaml
name: CI/CD Pipeline
on:
push:
branches:
- main
workflow_dispatch: # 수동 실행을 허용
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout application code
uses: actions/checkout@v3
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
id: docker_build
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: my-registry/my-app:${{ github.sha }} # Git SHA를 이미지 태그로 사용
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Checkout Kubernetes manifests repository
uses: actions/checkout@v3
with:
repository: your-org/your-infra-repo # Kubernetes Manifest 저장소
token: ${{ secrets.INFRA_REPO_TOKEN }} # Manifest 저장소 접근 토큰
path: infra-repo
- name: Update Kubernetes manifests with new image tag
run: |
cd infra-repo/apps/my-app/base
# Kustomize를 사용하여 이미지 태그 업데이트
kustomize edit set image my-registry/my-app=${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }}
# Git 설정
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
# 변경 사항 커밋 및 푸시
git add .
git commit -m "Update my-app image to my-registry/my-app:${{ github.sha }} [skip ci]" # CI 재트리거 방지
git push origin main
working-directory: infra-repo
설명:
-
DOCKER_USERNAME,DOCKER_PASSWORD는 Docker Hub 로그인 정보를 GitHub Secrets에 저장하여 사용합니다. -
INFRA_REPO_TOKEN은 Kubernetes Manifest 저장소에 커밋을 푸시할 수 있는 권한을 가진 GitHub Personal Access Token(PAT)입니다. 이 토큰은repo스코프 권한이 필요합니다. -
kustomize edit set image명령어를 사용하여kustomization.yaml파일 내의 이미지 태그를 자동으로 업데이트합니다. -
[skip ci]는 GitOps 파이프라인에서 무한 루프를 방지하기 위해 사용됩니다. Manifest 저장소에 변경이 푸시될 때 CI 파이프라인이 다시 트리거되는 것을 막습니다.
CD 파이프라인 구축: Argo CD 활용
CI 파이프라인이 새로운 Docker 이미지 태그로 Kubernetes Manifest 저장소를 업데이트하면, CD 도구인 Argo CD가 이 변경 사항을 감지하여 Kubernetes 클러스터에 배포를 시작합니다.
1. Argo CD 설치
Kubernetes 클러스터에 Argo CD를 설치합니다.
# Argo CD 네임스페이스 생성
kubectl create namespace argocd
# Argo CD 컨트롤러 및 관련 리소스 배포
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Argo CD API 서버 포트 포워딩 (로컬 접근용)
# kubectl port-forward svc/argocd-server -n argocd 8080:443
# Argo CD 초기 관리자 비밀번호 확인
# argocd-server Pod의 이름을 찾아 다음 명령어로 초기 비밀번호를 가져옵니다.
# kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d
2. Argo CD Application 리소스 정의
Kubernetes Manifest 저장소 내에 Argo CD Application 리소스를 정의하는 YAML 파일을 생성합니다. 이 파일은 Argo CD에게 어떤 Git 저장소의 어떤 경로를 모니터링할지, 그리고 어느 클러스터의 어느 네임스페이스에 배포할지를 알려줍니다.
# infra-repo/clusters/dev-cluster/argocd-app-my-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-dev # Argo CD 애플리케이션 이름
namespace: argocd # Argo CD가 설치된 네임스페이스
spec:
project: default # Argo CD 프로젝트 (기본값)
source:
repoURL: https://github.com/your-org/your-infra-repo.git # Kubernetes Manifest 저장소 URL
targetRevision: HEAD # 모니터링할 브랜치 (예: main)
path: apps/my-app/overlays/dev # Kustomize overlay 경로
destination:
server: https://kubernetes.default.svc # 대상 Kubernetes 클러스터 (현재 클러스터)
namespace: default # 애플리케이션이 배포될 네임스페이스
syncPolicy:
automated: # 자동 동기화 설정
prune: true # Git에 없는 리소스 제거
selfHeal: true # 클러스터 상태가 Git과 다를 경우 자동 복구
syncOptions:
- CreateNamespace=true # 대상 네임스페이스가 없으면 생성
이 argocd-app-my-app.yaml 파일 자체도 Kubernetes Manifest 저장소에 저장하고, 별도의 Argo CD Application이 이 파일을 배포하도록 설정하거나, Argo CD CLI를 통해 직접 생성할 수 있습니다.
# Argo CD CLI를 사용하여 Application 생성
argocd app create my-app-dev --repo https://github.com/your-org/your-infra-repo.git \
--path apps/my-app/overlays/dev \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--project default \
--sync-policy automated --auto-prune --self-heal \
--upsert # 이미 존재하면 업데이트
Argo CD는 이제 your-infra-repo 저장소의 apps/my-app/overlays/dev 경로를 지속적으로 모니터링하며, 변경 사항이 감지되면 자동으로 클러스터에 배포합니다.
환경별 배포 전략
GitOps에서는 Kustomize나 Helm Chart를 활용하여 개발, 스테이징, 운영 등 다양한 환경에 맞는 배포를 효율적으로 관리할 수 있습니다.
1. Kustomize를 이용한 환경별 오버레이
앞서 살펴본 Manifest 저장소 구조에서 base 디렉토리에 공통 설정을 두고, overlays 디렉토리에서 환경별로 필요한 패치를 적용하는 방식입니다.
apps/my-app/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
apps/my-app/overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base # 공통 base 리소스 포함
patches:
- path: deployment-patch.yaml
target:
kind: Deployment
name: my-app
apps/my-app/overlays/dev/deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1 # 개발 환경에서는 1개의 Pod만
template:
spec:
containers:
- name: my-app
env:
- name: NODE_ENV
value: "development"
apps/my-app/overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: deployment-patch.yaml
target:
kind: Deployment
name: my-app
apps/my-app/overlays/prod/deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # 운영 환경에서는 3개의 Pod
template:
spec:
containers:
- name: my-app
env:
- name: NODE_ENV
value: "production"
Argo CD Application을 생성할 때 path를 apps/my-app/overlays/dev 또는 apps/my-app/overlays/prod로 지정하여 각 환경에 맞는 Kustomize 설정을 배포할 수 있습니다.
2. Helm Chart와 Values 파일
Helm Chart를 사용하는 경우, Manifest 저장소에 Chart를 포함하고 환경별 values.yaml 파일을 관리할 수 있습니다.
infra-repo/
├── charts/
│ └── my-app-chart/
│ ├── Chart.yaml
│ ├── values.yaml # 기본 values
│ └── templates/
│ └── ...
└── environments/
├── dev/
│ └── my-app-values.yaml # 개발 환경 values 오버라이드
└── prod/
└── my-app-values.yaml # 운영 환경 values 오버라이드
Argo CD Application을 정의할 때 source.helm.valueFiles 옵션을 사용하여 환경별 values.yaml을 적용할 수 있습니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/your-infra-repo.git
targetRevision: HEAD
path: charts/my-app-chart # Chart 경로
helm:
valueFiles:
- environments/prod/my-app-values.yaml # 운영 환경 values 파일
destination:
server: https://kubernetes.default.svc
namespace: my-app-prod
syncPolicy:
automated:
prune: true
selfHeal: true
롤백 및 재해 복구
GitOps의 가장 큰 장점 중 하나는 강력한 롤백 기능과 재해 복구 능력입니다.
1. Git을 통한 롤백
잘못된 배포나 문제가 발생했을 경우, 단순히 Kubernetes Manifest 저장소에서 문제가 발생한 커밋을 git revert하거나 이전 상태로 git reset한 후 푸시하면 됩니다. Argo CD는 이 변경 사항을 감지하여 자동으로 클러스터를 이전 상태로 되돌립니다.
# 문제가 발생한 마지막 커밋 되돌리기
git revert HEAD --no-edit
# 변경 사항 푸시
git push origin main
2. Argo CD의 롤백 기능
Argo CD UI 또는 CLI를 통해서도 특정 Application의 이전 동기화 지점(Git 커밋)으로 롤백할 수 있습니다.
# Argo CD CLI를 이용한 롤백
argocd app rollback my-app-dev --revision <target_commit_sha>
3. 재해 복구 (Disaster Recovery)
GitOps는 클러스터 전체가 손실되는 재해 상황에서도 강력한 복구 능력을 제공합니다. 새로운 Kubernetes 클러스터를 프로비저닝한 후, Argo CD를 설치하고 Git 저장소의 Application 정의를 다시 배포하면, Argo CD가 자동으로 모든 애플리케이션과 인프라 리소스를 Git에 정의된 상태로 복원합니다. 이는 "인프라를 코드로 관리(Infrastructure as Code)"하는 GitOps의 진정한 힘을 보여줍니다.
마무리
GitOps는 현대 DevOps 환경에서 인프라 및 애플리케이션 배포의 자동화, 안정성, 투명성을 극대화하는 강력한 패러다임입니다. Git을 유일한 진실의 원천으로 삼고, 선언적인 방식으로 시스템 상태를 관리하며, Pull 기반의 자동화된 동기화를 통해 예측 가능하고 견고한 배포 워크플로우를 구축할 수 있습니다. 이 가이드에서 제시된 GitOps 핵심 원칙, 저장소 설계, CI/CD 파이프라인 구축 예시를 통해 여러분의 조직도 더욱 효율적이고 안정적인 시스템 운영을 달성하시길 바랍니다. GitOps 여정을 시작하며 지속적인 개선과 자동화를 통해 더 나은 개발 및 운영 환경을 만들어 나가는 것이 중요합니다.
관련 게시글
GitOps Workflow Design: Kubernetes CI/CD 자동화 가이드
GitOps 원칙을 기반으로 Kubernetes 환경에서 CI/CD 파이프라인을 설계하고 자동화하는 방법을 상세히 안내합니다. Docker, Argo CD, Helm을 활용한 효율적인 인프라 관리 전략을 다룹니다.
ArgoCD를 활용한 Kubernetes Continuous Delivery 심층 가이드
ArgoCD를 이용한 Kubernetes 환경에서의 GitOps 기반 지속적 배포(Continuous Delivery) 전략을 심층적으로 다룹니다. 설치부터 Application 관리, 고급 기능 및 DevOps 베스트 프랙티스까지, 자동화된 인프라 배포를 위한 가이드입니다.
Kubernetes Pod Service Deployment 심층 가이드
Kubernetes의 핵심 구성 요소인 Pod, Service, Deployment를 DevOps 관점에서 심층 분석하고, 실제 예시와 CLI 명령어를 통해 컨테이너 오케스트레이션의 기본기를 다집니다.