🎯 쿠버네티스 애플리케이션 롤링 업데이트와 동적 배포

📑 목차


1. 롤링 업데이트 기본 원리

핵심 개념

롤링 업데이트는 Deployment 리소스를 통해 무중단 서비스 업데이트를 제공하는 쿠버네티스의 핵심 기능입니다.

💡 업데이트 프로세스

🤔 질문: “기존 Pod를 한 번에 교체하지 않고 어떻게 점진적으로 업데이트할까?”

📋 구체적인 시나리오

실제 상황

  1. 문제: 3개의 Pod v1.0이 실행 중, v2.0으로 업데이트 필요
  2. 감지: 새 이미지 태그 적용 시 Deployment 컨트롤러가 새 ReplicaSet 생성
  3. 조치: 새 Pod 1개 생성 → 준비 완료 → 구 Pod 1개 종료 반복
  4. 결과: 서비스 중단 없이 모든 Pod가 새 버전으로 교체

💻 주요 설정 파라미터

# 📊 롤링 업데이트 상세 설정
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%          # 원하는 Pod 수 초과 허용 비율
      maxUnavailable: 25%    # 사용 불가 Pod 최대 비율
  minReadySeconds: 30        # 준비 상태 대기 시간
  revisionHistoryLimit: 10   # 롤백용 히스토리 보관 수

📊 상태 확인 옵션 비교

설정설명권장값
maxSurge: 50%빠른 배포리소스 여유시
maxUnavailable: 0고가용성 보장중요 서비스
minReadySeconds: 60안정성 중시복잡한 앱

2. kubectl set과 rollout 명령어

💡 kubectl set 명령어

📋 이미지 업데이트

# 이미지 변경 (즉시 롤링 업데이트 시작)
kubectl set image deployment/myapp container-name=new-image:v2.0
 
# 여러 컨테이너 동시 업데이트
kubectl set image deployment/myapp \
  frontend=myapp:v2.0 \
  backend=myapi:v1.5

📋 리소스 제한 설정

# CPU/메모리 제한 변경
kubectl set resources deployment/myapp -c=container-name \
  --limits=cpu=200m,memory=512Mi \
  --requests=cpu=100m,memory=256Mi
 
# 환경 변수 설정
kubectl set env deployment/myapp ENV_VAR=production

💡 kubectl rollout 명령어

📋 상태 확인 및 제어

# 롤아웃 상태 실시간 모니터링
kubectl rollout status deployment/myapp
 
# 배포 히스토리 확인
kubectl rollout history deployment/myapp
 
# 특정 리비전 상세 보기
kubectl rollout history deployment/myapp --revision=3
 
# 이전 버전으로 롤백
kubectl rollout undo deployment/myapp
 
# 특정 리비전으로 롤백
kubectl rollout undo deployment/myapp --to-revision=2

📋 일시 중지 및 재개 전략

# 1. 롤아웃 일시 중지
kubectl rollout pause deployment/myapp
 
# 2. 여러 변경사항 한 번에 적용
kubectl set image deployment/myapp app=myapp:v2.0
kubectl set env deployment/myapp DB_HOST=new-database
 
# 3. 롤아웃 재개 (한 번에 배포)
kubectl rollout resume deployment/myapp
 
# 4. 설정 변경 없이 재시작
kubectl rollout restart deployment/myapp

3. Kustomize 동적 배포

핵심 개념

Kustomize는 템플릿 없이 쿠버네티스 매니페스트를 환경별로 커스터마이징하는 도구입니다.

💡 Kustomize 구조 이해

📋 디렉토리 구조

project/
├── base/                          # 공통 베이스
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── metallb-namespace.yaml
│   └── kustomization.yaml
│
└── overlays/
    ├── dev/                       # 개발 환경
    │   └── kustomization.yaml    # v0.14.4, 레플리카: 1
    ├── staging/                   # 스테이징 환경
    │   └── kustomization.yaml    # v0.14.5, 레플리카: 2
    └── prod/                      # 프로덕션 환경
        └── kustomization.yaml    # v0.14.5, 레플리카: 5

💻 kustomization.yaml 예시

# 📊 base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
- metallb-namespace.yaml
- metallb-native-v0.14.4.yaml
 
images:
- name: quay.io/metallb/controller
  newTag: v0.14.5
- name: quay.io/metallb/speaker
  newTag: v0.14.5
# 📊 overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
- ../../base
 
patchesStrategicMerge:
- replica-count.yaml
 
images:
- name: quay.io/metallb/controller
  newTag: v0.14.6  # 프로덕션은 최신 안정 버전

💡 CRD와 MetalLB 이해

📋 CRD(Custom Resource Definition)란?

실제 상황

  1. 문제: 쿠버네티스 기본 리소스(Pod, Service)로는 부족
  2. 해결: MetalLB가 IPAddressPool, L2Advertisement 같은 커스텀 리소스 정의
  3. 결과: “쿠버네티스야, IPAddressPool 타입도 인식해줘” 확장

📋 MetalLB가 필요한 이유

# ❌ 베어메탈 환경에서 LoadBalancer 타입 생성 시
kubectl expose deployment nginx --type=LoadBalancer
# → EXTERNAL-IP가 <pending> 상태로 남음
 
# ✅ MetalLB 설치 후
kubectl expose deployment nginx --type=LoadBalancer
# → 실제 IP 주소 할당됨 (예: 192.168.1.100)

📊 MetalLB 모드 비교

모드특징사용 시기
Layer 2ARP 사용, 단순 설정소규모, 단일 노드 트래픽
BGP라우터 연동, 분산 처리대규모, 고가용성 필요

💻 동적 배포 워크플로우

# 1. kustomize 빌드 및 배포
kustomize build overlays/dev | kubectl apply -f -
 
# 2. 프로덕션 배포
kustomize build overlays/prod | kubectl apply -f -
 
# 3. 이미지 태그만 변경으로 업데이트
# kustomization.yaml에서 newTag: v0.14.6으로 수정 후
kustomize build overlays/prod | kubectl apply -f -

4. Helm으로 더 쉽게 배포하기

핵심 개념

Helm은 쿠버네티스의 “패키지 매니저”로, 복잡한 애플리케이션을 간단한 명령어로 설치하고 관리할 수 있습니다.

💡 Helm vs Kustomize 비교

📊 특징 비교표

구분KustomizeHelm
접근법YAML 패치 방식Go 템플릿 엔진
학습 곡선낮음중간
템플릿없음 (오버레이)있음 (조건문, 반복문)
패키지 관리없음있음 (Chart)
커뮤니티제한적풍부한 Chart 생태계

💡 Helm Chart 구조

📋 Chart 디렉토리 구조

nginx-chart/
├── Chart.yaml              # 차트 정보 (이름, 버전)
├── values.yaml             # 기본 설정값
├── values-dev.yaml         # 개발 환경 설정
├── values-prod.yaml        # 프로덕션 환경 설정
└── templates/              # 쿠버네티스 매니페스트 템플릿
    ├── deployment.yaml
    ├── service.yaml
    ├── ingress.yaml
    └── _helpers.tpl        # 공통 템플릿 함수

💻 values.yaml 예시

# 📊 기본 설정값 정의
replicaCount: 3
 
image:
  repository: nginx
  tag: "1.21.0"
  pullPolicy: IfNotPresent
 
service:
  type: LoadBalancer
  port: 80
 
ingress:
  enabled: false
  hosts:
    - host: nginx.example.com
 
resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 100m
    memory: 128Mi
 
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100

💡 실전 Helm 명령어

📋 설치 및 관리

# Chart 저장소 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add metallb https://metallb.github.io/metallb
 
# 저장소 업데이트
helm repo update
 
# Chart 검색
helm search repo nginx
 
# 설치
helm install my-nginx bitnami/nginx
 
# 환경별 설치
helm install frontend ./frontend-chart -f values-prod.yaml

📋 업데이트 및 롤백

# 업그레이드
helm upgrade my-nginx bitnami/nginx --set image.tag=1.22.0
 
# 설정 파일로 업그레이드
helm upgrade frontend ./frontend-chart -f values-prod-v2.yaml
 
# 롤백
helm rollback my-nginx 1
 
# 설치된 릴리스 확인
helm list
 
# 릴리스 상태 확인
helm status my-nginx
 
# 삭제
helm uninstall my-nginx

📋 MetalLB Helm 설치 예시

# MetalLB 설치
helm install metallb metallb/metallb \
  --set controller.image.tag=v0.14.5 \
  --set speaker.image.tag=v0.14.5 \
  --namespace metallb-system \
  --create-namespace
 
# 업그레이드
helm upgrade metallb metallb/metallb \
  --set controller.image.tag=v0.14.6
 
# 설정 확인
helm get values metallb

🎯 실전 kubectl 명령어 가이드

핵심 포인트

kubectl이 모든 도구의 기본입니다. Helm과 Kustomize도 결국 kubectl을 호출합니다.

💡 가장 많이 사용하는 명령어

📋 조회 계열

# Pod 목록 (가장 기본)
kubectl get pods
kubectl get pods -n metallb-system    # 특정 네임스페이스
kubectl get pods -A                   # 모든 네임스페이스
 
# 자세한 정보
kubectl describe pod my-pod-name
 
# 실시간 로그 (디버깅 필수!)
kubectl logs my-pod-name
kubectl logs -f my-pod-name           # 실시간 팔로우
kubectl logs my-pod-name --previous   # 이전 컨테이너 로그
 
# 전체 리소스 확인
kubectl get all
kubectl get deployments,services,pods

📋 디버깅 계열 (매우 중요!)

# Pod 안에 직접 접속
kubectl exec -it my-pod -- /bin/bash
 
# 포트 포워딩 (로컬에서 테스트)
kubectl port-forward pod/my-pod 8080:80
kubectl port-forward svc/my-service 3000:80
 
# 이벤트 확인 (문제 발생 시 필수)
kubectl get events --sort-by='.lastTimestamp'
 
# 리소스 사용량 확인
kubectl top pods
kubectl top nodes

📋 배포 및 업데이트

# YAML로 배포
kubectl apply -f deployment.yaml
 
# 직접 생성
kubectl create deployment nginx --image=nginx:1.21
 
# 이미지 변경 (롤링 업데이트 시작)
kubectl set image deployment/myapp container=nginx:1.22
 
# 스케일 조정
kubectl scale deployment myapp --replicas=5
 
# 환경변수 변경
kubectl set env deployment/myapp DB_HOST=new-host

💡 디버깅 시나리오별 접근법

📋 Pod가 안 뜰 때

# 1단계: 상태 확인
kubectl get pods
 
# 2단계: 상세 정보 (이미지 문제, 리소스 부족 등 확인)
kubectl describe pod problematic-pod
 
# 3단계: 로그 확인
kubectl logs problematic-pod
 
# 4단계: 이벤트 확인
kubectl get events --field-selector involvedObject.name=problematic-pod

📋 서비스 연결 안 될 때

# Service 확인
kubectl get svc
 
# Endpoint 확인 (Pod와 Service 연결 상태)
kubectl get endpoints
 
# Pod 내부에서 직접 테스트
kubectl exec -it test-pod -- curl my-service:80
 
# DNS 확인
kubectl exec -it test-pod -- nslookup my-service

💡 유용한 옵션과 단축어

📋 자주 쓰는 옵션

# 더 많은 정보 표시
kubectl get pods -o wide
 
# YAML 형식으로 출력
kubectl get pod my-pod -o yaml
 
# JSON 형식으로 출력
kubectl get pod my-pod -o json
 
# 실시간 감시
kubectl get pods -w
 
# 실제 실행 안 하고 확인만
kubectl apply -f deployment.yaml --dry-run=client
 
# 레이블로 선택
kubectl get pods -l app=nginx

📋 단축어 활용

# 리소스 타입 단축어
po = pods
svc = services
deploy = deployments
ns = namespaces
cm = configmaps
pv = persistentvolumes
pvc = persistentvolumeclaims
 
# 예시 사용
kubectl get po
kubectl describe svc nginx
kubectl delete deploy myapp

📋 alias 설정 (생산성 향상)

# ~/.bashrc 또는 ~/.zshrc에 추가
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kd='kubectl describe'
alias kl='kubectl logs'
alias kex='kubectl exec -it'
 
# 사용 예시
k get po
kgp -n dev
kl my-pod -f
kex my-pod -- /bin/bash

💡 네임스페이스와 컨텍스트 관리

📋 네임스페이스 관리

# 네임스페이스 생성
kubectl create namespace dev
 
# 기본 네임스페이스 변경
kubectl config set-context --current --namespace=dev
 
# 현재 설정 확인
kubectl config view --minify
 
# 모든 네임스페이스 리소스 조회
kubectl get pods --all-namespaces
# 또는
kubectl get pods -A

📋 컨텍스트 관리 (여러 클러스터)

# 현재 컨텍스트 확인
kubectl config current-context
 
# 컨텍스트 목록
kubectl config get-contexts
 
# 컨텍스트 변경
kubectl config use-context prod-cluster
 
# 새 컨텍스트 생성
kubectl config set-context dev --namespace=dev --cluster=minikube --user=minikube

학습 순서 추천

  1. 기본 조회: get, describe, logs
  2. 배포: apply, create, delete
  3. 디버깅: exec, port-forward, events
  4. 업데이트: set, scale, rollout
  5. 고급: patch, label, annotate

중요사항

kubectl을 마스터하면 Helm, Kustomize는 편의 도구로 느껴집니다. 실무에서는 kubectl로 문제를 진단하고 해결하는 시간이 가장 많습니다!


📚 참고자료