🚀 9-2 쿠버네티스 실습 시나리오

실습 환경

  • 클러스터: minikube, kind, 또는 멀티노드 클러스터
  • 필요 도구: kubectl, helm, curl
  • 예상 시간: 60-90분

📑 실습 목차


🎯 시나리오 1: 롤링 업데이트 마스터하기

📋 목표

  • 무중단 서비스 업데이트 경험
  • kubectl set/rollout 명령어 실습
  • 업데이트 전략 설정 및 롤백 실습

1단계: 기본 애플리케이션 배포

# 실습용 네임스페이스 생성
kubectl create namespace rolling-demo
kubectl config set-context --current --namespace=rolling-demo

deployment.yaml 생성:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: rolling-demo
  labels:
    app: webapp
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2         # 최대 2개 추가 Pod 허용
      maxUnavailable: 1   # 최대 1개 Pod 사용 불가 허용
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
        version: v1
    spec:
      containers:
      - name: webapp
        image: nginx:1.20-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "100m"
        # 헬스 체크 설정 (중요!)
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
  namespace: rolling-demo
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 80
  type: NodePort

배포 및 확인:

# 배포
kubectl apply -f deployment.yaml
 
# 상태 확인
kubectl get pods -w
kubectl get svc

2단계: 롤링 업데이트 실습

터미널 1 (모니터링):

# Pod 변화 실시간 감시
watch -n 1 'kubectl get pods -o wide'

터미널 2 (업데이트 실행):

# 1. 이미지 업데이트 (nginx 1.20 → 1.21)
kubectl set image deployment/webapp webapp=nginx:1.21-alpine
 
# 2. 롤아웃 상태 확인
kubectl rollout status deployment/webapp
 
# 3. 히스토리 확인
kubectl rollout history deployment/webapp
 
# 4. 추가 업데이트 (nginx 1.22)
kubectl set image deployment/webapp webapp=nginx:1.22-alpine --record
 
# 5. 환경변수 추가
kubectl set env deployment/webapp VERSION=v2

3단계: 롤백 실습

# 1. 현재 히스토리 확인
kubectl rollout history deployment/webapp
 
# 2. 특정 리비전 상세 확인
kubectl rollout history deployment/webapp --revision=2
 
# 3. 이전 버전으로 롤백
kubectl rollout undo deployment/webapp
 
# 4. 특정 리비전으로 롤백
kubectl rollout undo deployment/webapp --to-revision=1
 
# 5. 롤백 상태 확인
kubectl rollout status deployment/webapp

🎯 실습 과제

  1. maxSurge를 1로, maxUnavailable을 0으로 변경 후 업데이트 속도 비교
  2. readinessProbe를 제거하고 업데이트 시 어떤 일이 일어나는지 관찰
  3. 잘못된 이미지(nginx:nonexistent)로 업데이트 후 자동 롤백 확인

🔌 시나리오 2: MetalLB로 LoadBalancer 구현

📋 목표

  • MetalLB 설치 및 설정
  • LoadBalancer 타입 서비스 동작 확인
  • Layer 2 모드 실습

1단계: MetalLB 설치

# MetalLB 네임스페이스 및 설치
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml
 
# 설치 확인
kubectl get pods -n metallb-system
kubectl wait --for=condition=available --timeout=300s deployment/controller -n metallb-system

2단계: IP 주소 풀 설정

metallb-config.yaml:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: example-pool
  namespace: metallb-system
spec:
  addresses:
  # 🚨 주의: 실제 네트워크 환경에 맞게 수정하세요!
  # 홈 네트워크 예시: 192.168.1.240-192.168.1.250
  # minikube/kind 예시: 172.18.255.200-172.18.255.250
  - 192.168.1.240-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - example-pool

IP 범위 찾는 방법:

# 1. 현재 네트워크 확인
ip route | grep default
# 또는
route -n | grep UG
 
# 2. 사용 중인 IP 확인
nmap -sn 192.168.1.0/24  # 홈 네트워크 스캔
 
# 3. 사용 안 하는 IP 범위 선택
ping 192.168.1.240  # 응답 없으면 사용 가능

설정 적용:

# 설정 적용 (IP 범위 수정 후!)
kubectl apply -f metallb-config.yaml
 
# 설정 확인
kubectl get ipaddresspool -n metallb-system
kubectl get l2advertisement -n metallb-system

3단계: LoadBalancer 서비스 테스트

loadbalancer-test.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-lb-test
  namespace: rolling-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-lb-test
  template:
    metadata:
      labels:
        app: nginx-lb-test
    spec:
      containers:
      - name: nginx
        image: nginx:1.21-alpine
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        configMap:
          name: nginx-html
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-html
  namespace: rolling-demo
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head><title>MetalLB Test</title></head>
    <body>
      <h1>🎉 MetalLB 성공!</h1>
      <p>LoadBalancer 타입 서비스가 정상 동작 중입니다.</p>
      <p>Pod: nginx-lb-test</p>
      <p>시간: $(date)</p>
    </body>
    </html>
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
  namespace: rolling-demo
spec:
  type: LoadBalancer  # 🔥 핵심!
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx-lb-test

테스트 실행:

# 배포
kubectl apply -f loadbalancer-test.yaml
 
# LoadBalancer IP 할당 확인
kubectl get svc nginx-loadbalancer
# EXTERNAL-IP가 pending에서 실제 IP로 변경되는지 확인!
 
# 할당된 IP로 접속 테스트
EXTERNAL_IP=$(kubectl get svc nginx-loadbalancer -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "LoadBalancer IP: $EXTERNAL_IP"
curl http://$EXTERNAL_IP
 
# 브라우저에서도 접속 테스트
echo "브라우저에서 http://$EXTERNAL_IP 접속해보세요!"

🎯 실습 과제

  1. LoadBalancer 서비스를 NodePort로 변경했을 때 차이점 비교
  2. 여러 개의 LoadBalancer 서비스 생성하여 IP 할당 확인
  3. MetalLB Pod를 삭제했을 때 서비스 복구 과정 관찰

⚡ 시나리오 3: Helm으로 애플리케이션 배포

📋 목표

  • Helm Chart 생성 및 커스터마이징
  • 환경별 배포 실습
  • Helm으로 업그레이드/롤백 실습

1단계: Helm 환경 준비

# Helm 설치 확인
helm version
 
# Bitnami 저장소 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
 
# 사용 가능한 차트 검색
helm search repo nginx

2단계: 기본 Chart 배포

# 개발 환경 네임스페이스 생성
kubectl create namespace helm-demo
 
# nginx Chart 기본 설정값 확인
helm show values bitnami/nginx > nginx-default-values.yaml
 
# 기본 설치
helm install my-nginx bitnami/nginx \
  --namespace helm-demo \
  --set replicaCount=3 \
  --set service.type=LoadBalancer
 
# 설치 상태 확인
helm list -n helm-demo
helm status my-nginx -n helm-demo
kubectl get all -n helm-demo

3단계: 커스텀 values 파일 생성

nginx-custom-values.yaml:

# 복제본 설정
replicaCount: 3
 
# 이미지 설정
image:
  repository: nginx
  tag: "1.21-alpine"
  pullPolicy: IfNotPresent
 
# 서비스 설정
service:
  type: LoadBalancer
  port: 80
  targetPort: http
  nodePorts:
    http: ""
 
# 리소스 제한
resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 100m
    memory: 128Mi
 
# 커스텀 HTML 페이지
staticSiteConfigmap: |-
  <!DOCTYPE html>
  <html>
  <head>
    <title>Helm Demo App</title>
    <style>
      body { font-family: Arial; text-align: center; padding: 50px; }
      .version { color: #007acc; font-size: 2em; }
    </style>
  </head>
  <body>
    <h1>🚢 Helm으로 배포된 애플리케이션</h1>
    <p class="version">Version 1.0</p>
    <p>이 페이지는 Helm Chart로 배포되었습니다!</p>
  </body>
  </html>
 
# Ingress 설정 (선택사항)
ingress:
  enabled: false
 
# Pod 보안 설정
podSecurityContext:
  fsGroup: 1001
 
# 컨테이너 보안 설정  
containerSecurityContext:
  runAsUser: 1001
  runAsNonRoot: true

업그레이드 배포:

# 커스텀 설정으로 업그레이드
helm upgrade my-nginx bitnami/nginx \
  -f nginx-custom-values.yaml \
  -n helm-demo
 
# 업그레이드 상태 확인
helm status my-nginx -n helm-demo
kubectl get pods -n helm-demo

4단계: 환경별 배포 시나리오

개발 환경 (nginx-dev-values.yaml):

replicaCount: 1
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 50m
    memory: 64Mi
service:
  type: NodePort
staticSiteConfigmap: |-
  <html><body><h1>🛠️ 개발 환경</h1><p>Development Environment</p></body></html>

운영 환경 (nginx-prod-values.yaml):

replicaCount: 5
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi
service:
  type: LoadBalancer
staticSiteConfigmap: |-
  <html><body><h1>🚀 운영 환경</h1><p>Production Environment</p></body></html>

환경별 배포:

# 개발 환경
kubectl create namespace dev
helm install nginx-dev bitnami/nginx \
  -f nginx-dev-values.yaml \
  -n dev
 
# 운영 환경  
kubectl create namespace prod
helm install nginx-prod bitnami/nginx \
  -f nginx-prod-values.yaml \
  -n prod
 
# 모든 환경 확인
helm list -A
kubectl get svc -A | grep nginx

5단계: Helm 업그레이드 및 롤백

# 운영환경 레플리카 수 증가
helm upgrade nginx-prod bitnami/nginx \
  -f nginx-prod-values.yaml \
  --set replicaCount=8 \
  -n prod
 
# 히스토리 확인
helm history nginx-prod -n prod
 
# 이전 버전으로 롤백
helm rollback nginx-prod 1 -n prod
 
# 롤백 확인
kubectl get pods -n prod

🎯 실습 과제

  1. 자체 Chart 생성 (helm create my-app) 후 커스터마이징
  2. 템플릿 확인 (helm template) 으로 실제 YAML 출력 비교
  3. Helm hooks를 사용한 pre-install/post-install 작업 추가

🛠️ 시나리오 4: 통합 시나리오 - 실전 웹 애플리케이션 배포

📋 목표

  • 롤링 업데이트 + MetalLB + Helm 통합
  • CI/CD 파이프라인 시뮬레이션
  • 실제 운영 시나리오 경험

1단계: 멀티 티어 애플리케이션 Chart 생성

# 새 Chart 생성
helm create webapp-stack
cd webapp-stack

values.yaml (주요 부분):

# Frontend 설정
frontend:
  enabled: true
  replicaCount: 3
  image:
    repository: nginx
    tag: "1.21-alpine"
  service:
    type: LoadBalancer
    port: 80
 
# Backend 설정  
backend:
  enabled: true
  replicaCount: 2
  image:
    repository: httpd
    tag: "2.4-alpine"
  service:
    type: ClusterIP
    port: 8080
 
# Database 설정
database:
  enabled: true
  replicaCount: 1
  image:
    repository: redis
    tag: "6-alpine"
  service:
    type: ClusterIP
    port: 6379
 
# Global 설정
global:
  namespace: webapp-production

2단계: 배포 파이프라인 시뮬레이션

pipeline-script.sh:

#!/bin/bash
set -e
 
echo "🚀 배포 파이프라인 시작"
 
# 1단계: 네임스페이스 준비
echo "📁 네임스페이스 생성..."
kubectl create namespace webapp-production --dry-run=client -o yaml | kubectl apply -f -
 
# 2단계: 설정 검증
echo "🔍 Chart 검증..."
helm lint ./webapp-stack
 
# 3단계: 템플릿 확인 
echo "📋 템플릿 렌더링 확인..."
helm template webapp-production ./webapp-stack --dry-run
 
# 4단계: 배포 (또는 업그레이드)
echo "🚢 애플리케이션 배포..."
helm upgrade --install webapp-production ./webapp-stack \
  --namespace webapp-production \
  --wait \
  --timeout=5m
 
# 5단계: 배포 확인
echo "✅ 배포 상태 확인..."
helm status webapp-production -n webapp-production
kubectl get all -n webapp-production
 
# 6단계: 헬스 체크
echo "🔍 헬스 체크..."
kubectl wait --for=condition=available --timeout=300s deployment --all -n webapp-production
 
echo "🎉 배포 완료!"

3단계: 무중단 업데이트 시나리오

# 프론트엔드 버전 업데이트 (v1.21 → v1.22)
echo "📦 프론트엔드 업데이트 시작..."
helm upgrade webapp-production ./webapp-stack \
  --set frontend.image.tag=1.22-alpine \
  --namespace webapp-production \
  --wait
 
# 업데이트 진행상황 모니터링
kubectl rollout status deployment/webapp-stack-frontend -n webapp-production
 
# 백엔드 업데이트 (동시 모니터링)
watch -n 2 'kubectl get pods -n webapp-production'

4단계: 장애 시나리오 및 복구

# 1. 잘못된 이미지로 업데이트 (장애 시뮬레이션)
helm upgrade webapp-production ./webapp-stack \
  --set frontend.image.tag=nonexistent-version \
  --namespace webapp-production
 
# 2. 장애 상황 확인
kubectl get pods -n webapp-production
kubectl describe pod [failed-pod-name] -n webapp-production
 
# 3. 신속한 롤백
helm rollback webapp-production -n webapp-production
 
# 4. 복구 확인
kubectl get pods -n webapp-production
helm status webapp-production -n webapp-production

🎯 최종 실습 과제

  1. 성능 테스트: LoadBalancer IP로 부하테스트 수행
  2. 스케일링 테스트: HPA 설정 후 자동 스케일링 확인
  3. 재해복구: 전체 삭제 후 Helm으로 빠른 복구
  4. 모니터링: Prometheus + Grafana 연동

🔍 실습 검증 체크리스트

✅ 롤링 업데이트 마스터

  • 무중단 업데이트 성공
  • 업데이트 전략 설정 변경 테스트
  • 롤백 기능 활용
  • 헬스 체크 중요성 이해

✅ MetalLB 구현

  • LoadBalancer IP 할당 성공
  • 외부에서 웹 접속 확인
  • IP 풀 관리 이해
  • Layer 2 모드 동작 원리 파악

✅ Helm 마스터

  • Chart 설치/업그레이드/삭제
  • 커스텀 values 파일 작성
  • 환경별 배포 구분
  • 버전 관리 및 롤백

✅ 통합 시나리오

  • 멀티 컴포넌트 배포
  • 파이프라인 자동화 스크립트
  • 장애 대응 및 복구
  • 실전 운영 경험

실습 성공 팁

  1. 단계별 진행: 각 시나리오를 순서대로 완료
  2. 로그 확인: 문제 발생 시 kubectl logs 활용
  3. 상태 모니터링: watch 명령어로 실시간 확인
  4. 문서화: 실습 과정과 결과를 기록

📚 실습 후 참고자료