[GitOps] Kubernetes에 자동 배포하기
앞서 설명했듯이, GitHub Actions를 이용하면 코드를 푸시하는 것만으로도
자동으로 Docker 이미지 빌드 → Docker Hub 푸시 → GitOps 저장소 업데이트까지 완료된다.
하지만 아직 마지막 단계가 남아 있다.
바로 이 GitOps 저장소를 기반으로 Kubernetes 클러스터에 자동으로 배포하는 것이다.
이번 글에서는 AWS EC2 위에서 동작하는 쿠버네티스 클러스터에
ArgoCD를 이용해 애플리케이션을 자동 배포하는 과정을 설명한다.
🧭 1. GitOps란?
GitOps = Git + Ops(Operations)
GitOps는 배포 상태(Manifest, Helm 차트 등)를 Git으로 관리하고,
쿠버네티스가 이 저장소를 참조해 클러스터 상태를 자동으로 맞춰가는 방식이다.
“실제 배포 상태” = “Git에 정의된 상태
Git 변경 = 자동 배포
롤백 = Git 커밋 되돌리기
ArgoCD는 이 GitOps를 쉽게 구현할 수 있는 대표적인 툴이다.
🗂️ 2. GitOps 저장소 구조 이해하기
다음은 우리가 만든 GitOps 저장소(lunch-gitops)의 디렉토리 구조다.
base/
├─ backend-deploy.yaml
├─ backend-svc.yaml
├─ frontend-deploy.yaml
├─ frontend-svc.yaml
├─ kustomization.yaml
└─ namespace.yaml
📁 2-1. Namespace 생성
apiVersion: v1
kind: Namespace
metadata:
name: lunch
✅ 애플리케이션이 배포될 쿠버네티스 “공간”을 만든다.
(모든 리소스는 lunch 네임스페이스 안에서 동작한다.)
📁 2-2. 백엔드 Deployment (HA 자동복구 구성)
apiVersion: apps/v1
kind: Deployment
metadata:
name: lunch-backend
namespace: lunch
spec:
replicas: 1 # ⚙️ 단일 인스턴스 (중복 크롤링 방지)
revisionHistoryLimit: 3 # 이전 버전 3개까지 기록 (롤백용)
strategy:
type: RollingUpdate # 배포 중 무중단 유지
rollingUpdate:
maxUnavailable: 0 # 기존 Pod이 살아있는 동안 새 Pod 준비
maxSurge: 1 # 새 Pod을 하나 먼저 띄우고 교체
selector:
matchLabels:
app: lunch-backend
template:
metadata:
labels:
app: lunch-backend
spec:
nodeSelector:
role: backend # backend 역할 노드에만 스케줄링
restartPolicy: Always # Pod 비정상 종료 시 자동 재시작
containers:
- name: app
image: docker.io/도커허브아이디/lunch-backend:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: TZ
value: "Asia/Seoul"
resources:
requests:
cpu: "200m"
memory: "512Mi"
ephemeral-storage: "1Gi"
limits:
cpu: "600m"
memory: "1.5Gi"
ephemeral-storage: "2Gi"
volumeMounts:
- name: tmp
mountPath: /tmp # 크롬 임시 파일 저장 경로
volumes:
- name: tmp
emptyDir:
sizeLimit: "2Gi" # Pod 전용 임시 스토리지
✅ 특징 정리
nodeSelector: role=backend 레이블이 붙은 노드에만 배포
resources: 크롤링용 Chrome이 필요하므로 CPU·메모리·디스크 용량을 명시
emptyDir: 크롬 임시파일 저장용 디렉터리
replicas: 1 → 단일 인스턴스로 크롤링 중복 방지, 비정상 종료 시 자동 재시작
revisionHistoryLimit: 3 → 최근 3개 배포 이력 보관, 롤백 가능
strategy: RollingUpdate → 무중단 배포 설정 (기존 Pod 유지 후 교체)
📁 2-3. 백엔드 Service
apiVersion: v1
kind: Service
metadata:
name: lunch-backend
namespace: lunch
spec:
type: NodePort
selector: { app: lunch-backend }
ports:
- port: 8080
targetPort: 8080
nodePort: 30080
✅ 외부에서 백엔드 API(:30080)에 접근할 수 있도록 NodePort 서비스로 노출.
📁 2-4. 프론트엔드 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: lunch-frontend
namespace: lunch
spec:
replicas: 1
selector:
matchLabels: { app: lunch-frontend }
template:
metadata:
labels: { app: lunch-frontend }
spec:
nodeSelector:
role: frontend
containers:
- name: web
image: docker.io/도커허브아이디/lunch-frontend:latest
ports:
- containerPort: 80
env:
- name: TZ
value: "Asia/Seoul"
resources:
requests: { cpu: "50m", memory: "64Mi" }
limits: { cpu: "200m", memory: "256Mi" }
✅ 프론트엔드는 리소스 요구량이 작기 때문에 설정이 단순하다.
📁 2-5. 프론트엔드 Service
apiVersion: v1
kind: Service
metadata:
name: lunch-frontend
namespace: lunch
spec:
type: NodePort
selector: { app: lunch-frontend }
ports:
- port: 80
targetPort: 80
nodePort: 30030
✅ 웹 페이지는 30030 포트로 노출되어 브라우저에서 접속 가능하다.
📁 2-6. Kustomization 설정
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: lunch
resources:
- namespace.yaml
- backend-deploy.yaml
- backend-svc.yaml
- frontend-deploy.yaml
- frontend-svc.yaml
images:
- name: 도커허브 백엔드 이미지
newTag: d48acc234e56aac51224ff9f86e706d4b9b139cd
- name: 도커허브 프론트엔드 이미지
newTag: d48acc234e56aac51224ff9f86e706d4b9b139cd
✅ 핵심 포인트
resources: 배포할 리소스 목록을 한 번에 정의
images: CI/CD에서 자동으로 업데이트되는 이미지 태그
namespace: 모든 리소스를 lunch 네임스페이스로 지정
🚀 3. ArgoCD Application 생성
GitOps 저장소를 Kubernetes에 연결하려면 ArgoCD Application 리소스를 만들어야 한다.
lunch-argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: lunch
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/깃허브아이디/lunch-gitops.git
targetRevision: main
path: base
destination:
server: https://kubernetes.default.svc
namespace: lunch
syncPolicy:
automated:
prune: true
selfHeal: true
✅ 구성 요소 설명:
| repoURL | GitOps 저장소 주소 |
| targetRevision | 참조할 브랜치 (보통 main) |
| path | 매니페스트 파일이 있는 경로 |
| destination | 배포 대상 클러스터 및 네임스페이스 |
| syncPolicy.automated.prune | Git에서 삭제된 리소스도 자동 삭제 |
| syncPolicy.automated.selfHeal | 클러스터 상태가 Git과 다르면 자동 복구 |
🧪 4. 실제 배포 과정
이제 실제 배포는 단 2단계로 끝난다.
✅ 1) Application 적용
EC2 서버에서 다음 명령어를 실행:
kubectl apply -f lunch-argocd-app.yaml
✅ 2) ArgoCD 대시보드 확인
ArgoCD가 GitOps 저장소를 읽고 자동으로 다음을 수행한다:
네임스페이스 생성 (lunch)
백엔드/프론트엔드 디플로이먼트 생성
서비스(NodePort) 생성
결과는 아래 명령어로 확인할 수 있다:
kubectl get all -n lunch
예시 출력
NAME READY STATUS RESTARTS AGE
pod/lunch-backend-6c45fd6f65-abcde 1/1 Running 0 2m
pod/lunch-frontend-54cd66875f-fghij 1/1 Running 0 2m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/lunch-backend NodePort 10.109.89.155 <none> 8080:30080/TCP 2m
service/lunch-frontend NodePort 10.109.56.34 <none> 80:30030/TCP 2m
🧭 5. GitOps 배포 흐름 정리
CI/CD가 GitOps 저장소의 kustomization.yaml을 자동 업데이트한다.
ArgoCD는 Git 상태를 감지하고 클러스터 상태를 자동으로 동기화한다.
쿠버네티스 클러스터에는 최신 버전의 백엔드·프론트엔드가 자동 배포된다.
이미지 변경 → 커밋 → 자동 반영까지 한 번의 push로 끝!
이번 글에서는 GitOps 저장소의 구조와 각 매니페스트 파일의 역할을 살펴보고, ArgoCD를 이용해
AWS EC2 쿠버네티스 클러스터에 자동 배포하는 방법을 정리했다.
이제는 코드를 수정하고 푸시하는 것만으로도 서비스가 자동으로 업데이트된다.
이 흐름을 구축하면 운영 환경에서도 안전한 롤백과 자동화된 배포가 가능해지고,
개발자는 인프라를 신경 쓰지 않고 코드에만 집중할 수 있다 🚀
참고 GitHub 주소
BackEnd & FrontEnd : https://github.com/YangjiwooGN/LunchRecommendation.git
GitHub - YangjiwooGN/LunchRecommendation: Hyundai Autoever Cloud Mini Project
Hyundai Autoever Cloud Mini Project. Contribute to YangjiwooGN/LunchRecommendation development by creating an account on GitHub.
github.com
K8S Manifest : https://github.com/YangjiwooGN/lunch-gitops.git
GitHub - YangjiwooGN/lunch-gitops: Hyundai Autoever Cloud MiniProject Manifest
Hyundai Autoever Cloud MiniProject Manifest. Contribute to YangjiwooGN/lunch-gitops development by creating an account on GitHub.
github.com
'2025 현대오토에버 모빌리티 SW 스쿨(클라우드 2기) > 미니프로젝트' 카테고리의 다른 글
| [클라우드] CI/CD 자동화 과정 (0) | 2025.09.30 |
|---|---|
| [React] 프론트엔드 설계 (0) | 2025.09.27 |
| [Spring Boot] 백엔드 설계 (0) | 2025.09.27 |
| [프로젝트 설계] 주제 선정 및 프로젝트 설계 (0) | 2025.09.27 |