전체 비유: 입주민 관리 시스템#

Deployment를 아파트 입주민 관리 시스템에 비유하면 이해하기 쉽습니다:

아파트 관리 비유Kubernetes Deployment역할
입주민 관리 시스템Deployment세대(Pod) 배치와 업데이트 총괄
“항상 3세대 유지” 규칙replicas: 3원하는 세대 수 선언
세대 목록 관리대장ReplicaSet실제 세대 수 유지 담당
순차적 이사Rolling Update한 세대씩 새 버전으로 교체
이전 주소로 복귀Rollback문제 시 이전 상태로 되돌리기
공실 발생 시 자동 입주자동 복구Pod 장애 시 자동 재생성
입주 규격 템플릿Pod Template생성할 세대의 표준 사양
과거 입주 기록 보관revisionHistory롤백용 이전 버전 유지

이처럼 Deployment는 “관리사무소가 항상 일정 수의 세대를 유지하고, 리모델링 시 순차적으로 진행"하는 것과 같습니다.


대상 독자: Kubernetes에서 애플리케이션을 배포하고 싶은 백엔드 개발자 선수 지식: Pod 개념 소요 시간: 약 25-30분 이 문서를 읽으면: Deployment로 애플리케이션을 배포하고 업데이트하는 방법을 이해할 수 있습니다

TL;DR
  • Deployment는 Pod의 선언적 업데이트를 관리합니다
  • 롤링 업데이트로 무중단 배포가 가능합니다
  • 문제 발생 시 이전 버전으로 롤백할 수 있습니다

Deployment란?#

Deployment는 Pod의 배포와 업데이트를 관리하는 리소스입니다. Pod를 직접 관리하지 않고 Deployment를 사용하면 여러 이점이 있습니다.

기능설명
선언적 업데이트원하는 상태만 정의하면 Kubernetes가 알아서 처리
롤링 업데이트무중단으로 새 버전 배포
롤백문제 발생 시 이전 버전으로 되돌리기
스케일링replicas 조정으로 Pod 수 변경
자동 복구Pod 장애 시 자동 재생성

Deployment 구조#

Deployment는 ReplicaSet을 생성하고, ReplicaSet이 Pod를 관리합니다.

flowchart TB
    D[Deployment] --> RS[ReplicaSet]
    RS --> P1[Pod 1]
    RS --> P2[Pod 2]
    RS --> P3[Pod 3]

각 리소스의 역할을 비교하면 다음과 같습니다.

리소스역할
Deployment배포 전략 관리, ReplicaSet 버전 관리
ReplicaSet지정된 수의 Pod 복제본 유지
Pod실제 애플리케이션 컨테이너 실행
ReplicaSet을 직접 사용하지 않는 이유
ReplicaSet을 직접 만들 수도 있지만, 롤링 업데이트나 롤백 기능이 없습니다. Deployment가 이러한 기능을 제공하므로 항상 Deployment를 사용하세요.

Deployment YAML#

기본적인 Deployment 정의입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

주요 필드를 설명합니다.

필드설명
replicas유지할 Pod 수
selector.matchLabels관리할 Pod를 선택하는 기준
template생성할 Pod 템플릿
template.metadata.labelsPod에 붙일 레이블 (selector와 일치해야 함)

selector와 labels의 관계#

Deployment의 selector와 Pod의 labels는 반드시 일치해야 합니다.

spec:
  selector:
    matchLabels:
      app: my-app      # 이 레이블을 가진 Pod를 관리
  template:
    metadata:
      labels:
        app: my-app    # Pod에 이 레이블 부여 (위와 일치)

롤링 업데이트#

Deployment의 핵심 기능인 롤링 업데이트를 이해합니다.

롤링 업데이트 과정#

이미지 버전을 변경하면 롤링 업데이트가 시작됩니다.

sequenceDiagram
    participant D as Deployment
    participant RS1 as ReplicaSet v1
    participant RS2 as ReplicaSet v2

    Note over RS1: Pod v1 x 3

    D->>RS2: 새 ReplicaSet 생성
    RS2->>RS2: Pod v2 1개 시작
    RS1->>RS1: Pod v1 1개 종료

    RS2->>RS2: Pod v2 2개 시작
    RS1->>RS1: Pod v1 2개 종료

    RS2->>RS2: Pod v2 3개 시작
    RS1->>RS1: Pod v1 3개 종료

    Note over RS2: Pod v2 x 3

롤링 업데이트 단계별 상태#

replicas=3, maxSurge=1, maxUnavailable=0 설정 시:

단계v1 Podv2 Pod총 Pod가용 Pod설명
0 (시작 전)3033초기 상태
13143v2 Pod 1개 생성
22133v2 Ready 후 v1 1개 종료
32243v2 Pod 1개 추가 생성
41233v2 Ready 후 v1 1개 종료
51343v2 Pod 1개 추가 생성
6 (완료)0333마지막 v1 종료
핵심 포인트
maxUnavailable=0이므로 가용 Pod가 항상 3개 이상 유지됩니다. 새 Pod가 Ready가 된 후에만 이전 Pod를 종료합니다.

롤링 업데이트의 장점은 다음과 같습니다.

장점설명
무중단항상 일정 수의 Pod가 실행 중
점진적문제 발견 시 중단 가능
자동화별도 스크립트 불필요

업데이트 전략 설정#

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 원하는 수 대비 추가 허용 Pod
      maxUnavailable: 0  # 동시에 중단 가능한 Pod
설정의미예시 (replicas=3)
maxSurge: 1최대 4개까지 실행 허용3+1=4
maxUnavailable: 0최소 3개는 항상 실행절대 2개 이하 안 됨
maxSurge: 25%최대 4개까지 허용3*1.25=3.75→4

일반적인 전략을 비교하면 다음과 같습니다.

전략maxSurgemaxUnavailable특징
안전 우선10느리지만 안전
빠른 배포25%25%빠르지만 일시적 용량 감소
리소스 절약01추가 리소스 불필요

Recreate 전략#

모든 Pod를 종료 후 새로 생성하는 전략입니다.

spec:
  strategy:
    type: Recreate

사용하는 경우는 다음과 같습니다.

  • 이전 버전과 새 버전이 동시에 실행되면 안 되는 경우
  • 단일 인스턴스만 허용되는 애플리케이션
  • 데이터베이스 마이그레이션이 필요한 경우
주의
Recreate 전략은 다운타임이 발생합니다. 프로덕션에서는 신중하게 사용하세요.

롤백#

문제 발생 시 이전 버전으로 되돌립니다.

롤아웃 히스토리 확인#

# 배포 히스토리 확인
kubectl rollout history deployment/my-app

예상 출력:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

CHANGE-CAUSE를 기록하려면 배포 시 annotation을 추가합니다.

kubectl annotate deployment/my-app kubernetes.io/change-cause="이미지 버전 2.0으로 업데이트"

롤백 실행#

# 바로 이전 버전으로 롤백
kubectl rollout undo deployment/my-app

# 특정 버전으로 롤백
kubectl rollout undo deployment/my-app --to-revision=2

롤아웃 상태 확인#

# 롤아웃 진행 상태
kubectl rollout status deployment/my-app

# 롤아웃 일시 중지
kubectl rollout pause deployment/my-app

# 롤아웃 재개
kubectl rollout resume deployment/my-app

스케일링#

Pod 수를 조정하여 트래픽 변화에 대응합니다.

수동 스케일링#

# replicas를 5로 변경
kubectl scale deployment/my-app --replicas=5

# 또는 YAML 수정
kubectl edit deployment/my-app

스케일링 시 주의사항#

고려사항설명
리소스 확인노드에 충분한 리소스가 있는지
연결 수DB 연결 풀, 외부 API 제한
세션 관리Sticky Session 필요 여부
스토리지RWO 볼륨은 여러 Pod에서 공유 불가

실습: Deployment 배포와 업데이트#

Deployment 생성#

# Deployment 생성
kubectl apply -f deployment.yaml

# 상태 확인
kubectl get deployment my-app
kubectl get replicaset
kubectl get pods -l app=my-app

이미지 업데이트#

# 이미지 변경으로 롤링 업데이트 트리거
kubectl set image deployment/my-app app=my-app:2.0

# 롤아웃 상태 모니터링
kubectl rollout status deployment/my-app

# Pod가 교체되는 과정 확인
kubectl get pods -w

ReplicaSet 확인#

# ReplicaSet 목록 - 이전 버전도 유지됨
kubectl get rs

# 예상 출력:
# NAME                  DESIRED   CURRENT   READY   AGE
# my-app-7d8f9b7c5f     3         3         3       10m
# my-app-5b9f8c6d4e     0         0         0       30m

이전 ReplicaSet이 유지되는 이유는 롤백을 위해서입니다. revisionHistoryLimit으로 보관 개수를 설정할 수 있습니다.

spec:
  revisionHistoryLimit: 3  # 최근 3개 버전만 유지

롤백 실습#

# 의도적으로 잘못된 이미지 배포
kubectl set image deployment/my-app app=my-app:invalid

# 롤아웃 상태 확인 (실패)
kubectl rollout status deployment/my-app

# Pod 상태 확인
kubectl get pods
# ImagePullBackOff 상태의 Pod 확인

# 롤백
kubectl rollout undo deployment/my-app

# 복구 확인
kubectl get pods

자주 사용하는 kubectl 명령어#

명령어설명
kubectl get deploymentDeployment 목록
kubectl describe deployment <name>상세 정보
kubectl rollout status deployment/<name>롤아웃 상태
kubectl rollout history deployment/<name>버전 히스토리
kubectl rollout undo deployment/<name>롤백
kubectl scale deployment/<name> --replicas=N스케일링
kubectl set image deployment/<name> <container>=<image>이미지 변경

프로덕션 권장 설정#

실제 운영을 위한 Deployment 예시입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

권장 설정 체크리스트는 다음과 같습니다.

항목이유
resources 설정리소스 경합 방지, 스케줄링 정확도
readinessProbe준비되지 않은 Pod에 트래픽 방지
livenessProbe멈춘 Pod 자동 재시작
maxUnavailable: 0무중단 배포 보장
revisionHistoryLimit롤백 가능 버전 관리

다음 단계#

Deployment를 이해했다면 다음 단계로 진행하세요:

목표추천 문서
Pod에 접근하기Service
자동 스케일링스케일링
헬스 체크 설정헬스 체크