k8s 1주 3일차 - 배포 전략

진웅·2025년 5월 26일

K8S Basics

목록 보기
3/40

Kubernetes 3일차: 배포 전략과 워크로드 관리

🎯 학습 목표

  • Pod를 넘어선 다양한 워크로드 타입 이해
  • 각 배포 방식의 특징과 사용 사례 파악
  • 실제 운영 환경에서의 배포 전략 습득

📋 목차

  1. 워크로드 타입 개요
  2. Deployment 실습
  3. ReplicaSet 이해하기
  4. DaemonSet 실습
  5. StatefulSet 실습
  6. Job과 CronJob
  7. 배포 전략 비교

1. 워크로드 타입 개요

🤔 왜 Pod 직접 사용은 권장되지 않을까?

2일차에서 nginx Pod를 직접 생성해봤지만, 실제 운영에서는 다음과 같은 문제가 있습니다:

  • 가용성: Pod가 죽으면 자동으로 재시작되지 않음
  • 확장성: 트래픽 증가 시 수동으로 Pod를 늘려야 함
  • 업데이트: 무중단 배포가 어려움
  • 관리: 여러 Pod 관리가 복잡함

📊 Kubernetes 워크로드 타입들

워크로드 타입용도특징
Deployment일반적인 애플리케이션무중단 배포, 롤백, 스케일링
ReplicaSetPod 복제본 관리Deployment가 내부적으로 사용
DaemonSet모든 노드에서 실행로깅, 모니터링 에이전트
StatefulSet상태가 있는 애플리케이션데이터베이스, 순서가 중요한 앱
Job일회성 작업배치 처리, 백업
CronJob스케줄 작업정기적인 배치 작업

❓ 상태가 있다 없다(Stateful or Stateless) 의 실제적 의미

  • pod가 재시작한 경우에 ,
    • IP 가 유지되는가?
    • pod명은 유지되는가 ?

2. Deployment 실습

🚀 첫 번째 Deployment 생성

# nginx-deployment.yaml
# Kubernetes API 버전을 지정합니다. Deployment는 apps/v1 API 그룹을 사용합니다.
# 이는 Kubernetes가 이 YAML을 올바른 API로 처리하도록 합니다.
apiVersion: apps/v1

# 리소스 유형을 정의합니다. 여기서는 Deployment로, 스테이트리스 애플리케이션을 관리합니다.
kind: Deployment

# Deployment의 메타데이터를 정의합니다. 이름, 네임스페이스, 라벨 등을 포함합니다.
metadata:
  # Deployment의 고유 이름입니다. 클러스터 내에서 고유해야 합니다.
  name: nginx-deployment
  # Deployment가 배포될 네임스페이스입니다. 지정하지 않으면 'default'가 기본값입니다.
  namespace: default
  # Deployment 자체를 식별하기 위한 라벨입니다. 관리 및 쿼리에 사용됩니다.
  labels:
    app: nginx

# Deployment의 원하는 상태(desired state)를 정의합니다.
spec:
  # 실행할 Pod의 개수를 지정합니다. 여기서는 3개의 Pod를 유지합니다.
  replicas: 3
  # Deployment가 관리할 Pod를 선택하기 위한 라벨 셀렉터입니다.
  selector:
    # Pod의 라벨과 일치해야 합니다. 여기서는 app=nginx인 Pod를 관리합니다.
    matchLabels:
      app: nginx
  # Pod의 템플릿을 정의합니다. Deployment가 생성할 Pod의 모양을 지정합니다.
  template:
    # Pod의 메타데이터입니다. 주로 라벨을 정의합니다.
    metadata:
      # Pod에 붙일 라벨입니다. selector.matchLabels와 일치해야 합니다.
      labels:
        app: nginx
    # Pod의 세부 설정(PodSpec)을 정의합니다. 컨테이너, 볼륨, 리소스 등을 포함합니다.
    spec:
      # Pod 내에서 실행할 컨테이너 목록입니다.
      containers:
      # 컨테이너의 이름입니다. Pod 내에서 고유해야 합니다.
      - name: nginx
        # 사용할 컨테이너 이미지입니다. 'nginx:latest'는 최신 nginx 이미지를 사용합니다.
        image: nginx:latest
        # 컨테이너가 노출할 포트를 정의합니다.
        ports:
        # 컨테이너 내부에서 열 포트입니다. 여기서는 HTTP 포트 80을 엽니다.
        - containerPort: 80
        # 컨테이너의 리소스 요청(requests)과 제한(limits)을 정의합니다.
        resources:
          # 최소 필요한 리소스를 지정합니다. 스케줄링 시 노드 선택에 사용됩니다.
          requests:
            # 최소 0.1 CPU 코어(100 milliCPU)를 요청합니다.
            cpu: "100m"
            # 최소 128MB 메모리를 요청합니다.
            memory: "128Mi"
          # 최대 사용 가능한 리소스를 제한합니다. 이를 초과하면 컨테이너가 종료될 수 있습니다.
          limits:
            # 최대 0.2 CPU 코어(200 milliCPU)를 사용할 수 있습니다.
            cpu: "200m"
            # 최대 256MB 메모리를 사용할 수 있습니다.
            memory: "256Mi"

📝 실습 1: 기본 Deployment 배포

# 1. Deployment 생성
kubectl apply -f nginx-deployment.yaml

# 2. 상태 확인
kubectl get deployments
kubectl get pods
kubectl get replicasets

# 3. 세부 정보 확인
kubectl describe deployment nginx-deployment

🔍 관찰 포인트:

  • 3개의 Pod가 생성되는지 확인
  • ReplicaSet이 자동으로 생성되는지 확인
  • Pod 이름의 패턴 확인

📝 실습 2: 스케일링 테스트

# 1. 수동 스케일링
kubectl scale deployment nginx-deployment --replicas=5

# 2. 상태 확인
kubectl get pods -w

# 3. 스케일 다운
kubectl scale deployment nginx-deployment --replicas=2

📝 실습 3: 롤링 업데이트

# 1. 현재 이미지 확인
kubectl describe deployment nginx-deployment | grep Image

# 2. 이미지 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:1.22

# 3. 롤아웃 과정 관찰
kubectl rollout status deployment/nginx-deployment
kubectl get pods -w

# 4. 롤아웃 히스토리 확인
kubectl rollout history deployment/nginx-deployment

📝 실습 4: 롤백 테스트

# 1. 문제가 있는 이미지로 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:invalid-tag

# 2. 상태 확인 (실패 확인)
kubectl get pods
kubectl describe pod [pod-name]

# 3. 롤백 실행
kubectl rollout undo deployment/nginx-deployment

# 4. 롤백 확인
kubectl rollout status deployment/nginx-deployment

3. ReplicaSet 이해하기

🔍 ReplicaSet 분석

# 1. ReplicaSet 상세 정보
kubectl get replicasets -o wide
kubectl describe replicaset [replicaset-name]

# 2. ReplicaSet과 Pod 관계 확인
kubectl get pods --show-labels

📝 실습 5: Pod 자동 복구 테스트

# 1. Pod 하나 삭제
kubectl delete pod [pod-name]

# 2. 자동 복구 관찰
kubectl get pods -w

# 3. ReplicaSet 이벤트 확인
kubectl describe replicaset [replicaset-name]

4. DaemonSet 실습

🌐 DaemonSet 이해

DaemonSet은 클러스터의 모든 노드(또는 특정 노드)에서 Pod를 실행합니다.

# fluentd-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-daemonset
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluent/fluentd:v1.12
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi

📝 실습 6: DaemonSet 배포

# 1. DaemonSet 생성
kubectl apply -f fluentd-daemonset.yaml

# 2. 상태 확인
kubectl get daemonsets
kubectl get pods -o wide

# 3. 노드별 Pod 분포 확인
kubectl get pods --all-namespaces -o wide | grep fluentd

5. StatefulSet 실습

💾 StatefulSet 특징

  • 순서가 있는 배포 및 스케일링
  • 안정적인 네트워크 식별자
  • 영구 스토리지
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-statefulset
spec:
  serviceName: mysql-service
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "true"
        ports:
        - containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
  - port: 3306

📝 실습 7: StatefulSet 배포

# 1. StatefulSet 및 Service 생성
kubectl apply -f mysql-statefulset.yaml

# 2. 순차 배포 관찰
kubectl get pods -w

# 3. Pod 이름 패턴 확인
kubectl get pods
# mysql-statefulset-0, mysql-statefulset-1, mysql-statefulset-2

# 4. 스케일링 테스트
kubectl scale statefulset mysql-statefulset --replicas=5
kubectl get pods -w

6. Job과 CronJob

⚡ Job - 일회성 작업

# batch-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    spec:
      containers:
      - name: batch-worker
        image: busybox
        command: ["sh", "-c", "echo 'Batch job started'; sleep 30; echo 'Batch job completed'"]
      restartPolicy: Never
  backoffLimit: 4

📝 실습 8: Job 실행

# 1. Job 생성
kubectl apply -f batch-job.yaml

# 2. Job 상태 확인
kubectl get jobs
kubectl get pods

# 3. Job 로그 확인
kubectl logs [job-pod-name]

# 4. Job 완료 후 상태
kubectl get jobs
kubectl describe job batch-job

⏰ CronJob - 스케줄된 작업

# backup-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: backup-cronjob
spec:
  schedule: "*/2 * * * *"  # 2분마다 실행
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: busybox
            command: ["sh", "-c", "echo 'Backup started at $(date)'; sleep 10; echo 'Backup completed'"]
          restartPolicy: OnFailure

📝 실습 9: CronJob 설정

# 1. CronJob 생성
kubectl apply -f backup-cronjob.yaml

# 2. CronJob 상태 확인
kubectl get cronjobs

# 3. 실행되는 Job들 관찰
kubectl get jobs -w

# 4. 특정 실행 로그 확인
kubectl logs [cronjob-pod-name]

7. 배포 전략 비교

📊 실습 10: 성능 및 동작 비교

# 1. 현재 실행 중인 모든 워크로드 확인
kubectl get all

# 2. 각 워크로드의 특징 관찰
echo "=== Deployments ==="
kubectl get deployments -o wide

echo "=== DaemonSets ==="
kubectl get daemonsets -o wide

echo "=== StatefulSets ==="
kubectl get statefulsets -o wide

echo "=== Jobs ==="
kubectl get jobs

echo "=== CronJobs ==="
kubectl get cronjobs

🧪 장애 복구 테스트

# 1. 각 워크로드의 Pod 하나씩 강제 삭제
kubectl delete pod [deployment-pod-name]
kubectl delete pod [daemonset-pod-name]
kubectl delete pod [statefulset-pod-name]

# 2. 복구 동작 관찰
kubectl get pods -w

# 3. 복구 시간과 방식 비교 분석

📋 사용 사례별 권장사항

시나리오권장 워크로드이유
웹 애플리케이션Deployment무중단 배포, 쉬운 스케일링
로그 수집기DaemonSet모든 노드에서 실행 필요
데이터베이스StatefulSet상태 보존, 순서 있는 배포
이미지 처리Job일회성 배치 작업
백업 작업CronJob정기적 실행

🧹 정리 및 리소스 삭제

📝 실습 11: 리소스 정리

# 1. 생성한 모든 리소스 확인
kubectl get all

# 2. Deployment 삭제
kubectl delete deployment nginx-deployment

# 3. DaemonSet 삭제
kubectl delete daemonset fluentd-daemonset

# 4. StatefulSet 삭제 (Service 포함)
kubectl delete statefulset mysql-statefulset
kubectl delete service mysql-service

# 5. Job 삭제
kubectl delete job batch-job

# 6. CronJob 삭제
kubectl delete cronjob backup-cronjob

# 7. 최종 확인
kubectl get all

📚 핵심 정리

✅ 오늘 배운 내용

  1. Deployment: 가장 일반적인 배포 방식, 무중단 배포와 롤백 지원
  2. DaemonSet: 모든 노드에서 실행되는 시스템 레벨 애플리케이션
  3. StatefulSet: 상태가 있는 애플리케이션을 위한 순서 있는 배포
  4. Job/CronJob: 배치 작업과 스케줄된 작업 처리

🎯 다음 단계

  • Service와 Ingress를 통한 네트워킹
  • ConfigMap과 Secret을 통한 설정 관리
  • PersistentVolume을 통한 데이터 영속성
  • 모니터링과 로깅 설정

💡 실습 후 생각해볼 점

  1. 각 워크로드 타입은 언제 사용하는 것이 적절한가?
  2. 운영 환경에서 고려해야 할 추가 설정은 무엇인가?
  3. 장애 발생 시 각 워크로드는 어떻게 대응하는가?

📖 추가 학습 자료

명령어 치트시트

# 배포 관련
kubectl apply -f [file]
kubectl scale deployment [name] --replicas=[number]
kubectl set image deployment/[name] [container]=[image]
kubectl rollout status deployment/[name]
kubectl rollout undo deployment/[name]

# 상태 확인
kubectl get [resource-type]
kubectl describe [resource-type] [name]
kubectl logs [pod-name]

# 정리
kubectl delete [resource-type] [name]

이제 Pod 단위가 아닌 실제 운영에 적합한 다양한 배포 전략을 이해하고 실습해보셨습니다!

profile
bytebliss

0개의 댓글