[IT-정보] 디플로이먼트 개념 완벽 정리 – 쿠버네티스 운영의 핵심 기초와 동작 원리

디플로이먼트 관련 쿠버네티스 구조를 설명하는 대표 이미지

디플로이먼트가 왜 운영의 핵심일까요

새벽 2시에 갑자기 서비스 장애 알람이 울리는 상황을 상상해 보세요. 개발팀은 급하게 서버를 수정해서 다시 배포하려고 하지만, 수십 개의 포드(Pod)를 하나씩 수동으로 교체하는 것은 불가능에 가까워요. 만약 배포 도중에 새로운 버전의 애플리케이션에 버그가 있다면 어떻게 될까요? 기존에 잘 돌아가던 서비스까지 한꺼번에 중단되는 대형 사고로 이어질 수 있습니다.

이런 혼란을 막기 위해 쿠버네티스 운영자는 디플로이먼트 개념을 반드시 완벽하게 이해하고 있어야 해요. 단순히 명령어를 입력하는 수준을 넘어, 시스템이 어떻게 스스로 상태를 유지하고 변화를 관리하는지 알아야 실무에서 발생하는 돌발 상황에 유연하게 대처할 수 있습니다. 디플로이먼트는 단순한 배포 도구가 아니라, 우리가 정의한 “원하는 상태”를 클러스터가 스스로 추적하게 만드는 강력한 컨트롤러예요.

많은 테크리드와 엔지니어들이 처음 쿠버네티스를 접할 때 포드(Pod)를 직접 생성하는 것부터 시작하곤 합니다. 하지만 포드를 개별적으로 관리하는 방식은 확장이 어렵고 장애 복구에 매우 취약해요. 규모가 커질수록 관리해야 할 포드의 개수는 기하급수적으로 늘어나고, 사람이 일일이 개입하는 순간 운영의 효율성은 급격히 떨어집니다. 수동 관리의 한계는 곧 서비스의 불안정성으로 직결됩니다.

본 가이드를 통해 여러분은 다음과 같은 핵심 내용을 체계적으로 학습하게 됩니다.

  • 디플로이먼트의 핵심 정의와 포드 및 레플리카셋과의 관계
  • 선언적 명령(Declarative) 방식에 따른 내부 동작 원리
  • 실무에서 즉시 활용 가능한 YAML 설정 예제와 전략
  • 배포 중 발생하는 주요 실수와 트러블슈팅 방법

이제 막연하게 느껴졌던 쿠버네티스 배포의 세계를 디플로이먼트를 중심으로 하나씩 파헤쳐 보도록 하겠습니다.

디플로이먼트를 이해하기 위한 사전 준비

디플로이먼트의 동작 방식을 깊이 있게 이해하려면, 그 밑바닥에서 작동하는 구성 요소들의 계층 구조를 먼저 파악해야 해요. 디플로이먼트는 단독으로 존재하는 것이 아니라, 레플리카셋(ReplicaSet)포드(Pod)를 관리하는 상위 개념이기 때문입니다.

관리 계층의 삼각관계 파악하기

쿠버네티스에서 애플리케이션을 관리하는 구조는 마치 기업의 조직도와 비슷해요. 가장 말단에 있는 포드는 실제 업무를 수행하는 사원이고, 레플리카셋은 특정 인원수를 유지하도록 관리하는 팀장이며, 디플로이먼트는 전체적인 프로젝트 방향을 결정하고 팀을 교체하는 본부장 역할을 수행한다고 볼 수 있습니다. 이 관계를 이해하지 못하면 배포 전략을 세울 때 왜 특정 설정이 필요한지 알 수 없게 됩니다.

💡 알아두기
디플로이먼트는 직접 포드를 관리하지 않아요. 디플로이먼트는 레플리카셋을 관리하고, 레플리카셋이 실제 포드의 개수를 조절하는 구조를 가지고 있습니다.

구성 요소별 역할 비교

운영 환경에서 어떤 객체를 사용해야 할지 판단하기 위해, 핵심 구성 요소들의 차이점을 명확히 알고 있어야 합니다. 아래 표를 통해 각 객체의 목적과 특징을 비교해 보세요.

객체 유형 주요 목적 핵심 기능 관리 단위
포드(Pod) 컨테이너 실행 가장 작은 배포 단위 단일 애플리케이션 컨테이너
레플리카셋(ReplicaSet) 수량 유지 지정된 포드 개수 보장 포드 그룹
디플로이먼트(Deployment) 버전 관리 및 배포 롤링 업데이트 및 롤백 지원 레플리카셋 세트

설정 전 체크리스트

실무에서 디플로이먼트를 적용하기 전에 반드시 다음 세 가지 기준을 검토해야 합니다. 단순히 작동하는 것을 넘어, 안정적인 운영을 위한 판단 기준이 됩니다.

  • 상태의 선언성: 명령어로 하나씩 수정할 것인가, 아니면 YAML 파일에 원하는 상태를 적어두고 시스템에 맡길 것인가를 결정해야 해요. 쿠버네티스에서는 후자가 표준입니다.
  • 가용성 요구사항: 업데이트 중에 서비스 중단이 허용되는지, 아니면 무조건 무중단 배포(Rolling Update)가 필요한지 확인하세요.
  • 복구 전략: 배포 실패 시 즉시 이전 버전으로 돌아갈 수 있는 롤백 환경이 준비되었는지 체크가 필요합니다.

이러한 사전 지식을 갖추고 나면, 이제 실제로 디플로이먼트가 어떻게 동작하며 어떻게 설정하는지 구체적인 단계를 살펴볼 준비가 된 것입니다.

디플로이먼트 동작 원리와 단계별 실행 가이드

디플로이먼트는 단순한 명령 전달자가 아닙니다. 클러스터 내부에서 끊임없이 “현재 상태”와 “사용자가 정의한 상태”를 비교하며 그 간극을 메우는 지능적인 시스템이에요. 이제 실제 배포 과정이 어떻게 진행되는지 단계별로 자세히 알아보겠습니다.

STEP 1. 원하는 상태를 정의하는 YAML 작성하기

디플로이먼트 운영의 시작은 선언적 API(Declarative API)를 사용하는 것입니다. 우리는 무엇을 할지(Do)를 명령하는 것이 아니라, 결과가 어떠해야 하는지(Be)를 YAML 파일에 기술합니다. 이 파일에는 크게 세 가지 핵심 영역이 포함됩니다.

  • metadata: 디플로이먼트의 이름, 네임스페이스, 라벨 등 객체를 식별하기 위한 정보예요.
  • spec.replicas: 우리가 유지하고 싶은 포드의 개수를 지정합니다. 만약 3으로 설정하면, 시스템은 어떤 상황에서도 3개의 포드가 떠 있도록 노력해요.
  • spec.selector: 이 디플로이먼트가 어떤 포드들을 자신의 소유로 관리할지 결정하는 규칙입니다. 라벨(Label)을 기반으로 포드를 찾아냅니다.
  • spec.template: 실제로 생성될 포드의 설계도입니다. 어떤 컨테이너 이미지를 쓸지, 포트 번호는 무엇인지 등을 정의합니다.

여기서 가장 주의해야 할 점은 selector와 template의 라벨이 반드시 일치해야 한다는 점이에요. 이 규칙이 깨지면 디플로이먼트는 자신이 만든 포드를 찾지 못해 무한 루프에 빠지게 됩니다.

STEP 2. 컨트롤러 루프를 통한 상태 동기화

YAML 파일을 적용(apply)하면 쿠버네티스의 컨트롤 플레인은 동작을 시작합니다. 디플로이먼트 컨트롤러는 일종의 “무한 루프”를 돌며 다음 과정을 반복해요.

  1. 관찰(Observe): 현재 클러스터에 떠 있는 포드들의 상태와 라벨을 확인합니다.
  2. 차이 분석(Diff): 사용자가 YAML에 적어놓은 ‘원하는 상태’와 ‘현재 상태’를 비교합니다. 예를 들어, 사용자는 3개를 원하는데 현재 0개라면 차이는 3입니다.
  3. 조치(Act): 차이를 메우기 위해 레플리카셋을 생성하거나, 포드를 추가/삭제하는 명령을 내립니다.

이 과정을 통해 우리는 서버가 죽거나 포드가 예기치 않게 종료되어도, 시스템이 스스로 판단하여 다시 포드를 살려내는 자가 치유(Self-healing) 능력을 경험하게 됩니다.

STEP 3. 무중단 배포를 위한 롤링 업데이트 적용

애플리케이션의 버전을 v1에서 v2로 올릴 때, 모든 포드를 한꺼번에 끄고 새로 켜는 것은 위험합니다. 서비스 중단 시간이 발생하기 때문이죠. 이때 사용하는 것이 바로 롤링 업데이트(Rolling Update) 전략입니다.

롤링 업데이트는 다음과 같은 순서로 진행됩니다. 먼저 새 버전(v2)의 포드를 하나 생성합니다. 새 포드가 정상적으로 작동하는지 확인(Readiness Probe)되면, 기존 버전(v1)의 포드를 하나 삭제합니다. 이 과정을 반복하여 결국 모든 포드가 v2로 교체됩니다. 이 과정에서 서비스는 끊김 없이 계속 유지됩니다.

💡 알아두기
롤링 업데이트의 속도를 조절하려면 `maxSurge`(한 번에 추가될 수 있는 최대 포드 수)와 `maxUnavailable`(업데이트 중 사용 불가능한 최대 포드 수) 설정을 조정하세요. 이를 통해 배포 속도와 서비스 가용성 사이의 균형을 맞출 수 있습니다.

STEP 4. 실무용 디플로이먼트 설정 예제 분석

이해를 돕기 위해 실제 운영 환경에서 자주 쓰이는 표준적인 YAML 구조를 살펴보겠습니다. 이 예제를 통해 각 필드가 어떤 의미를 갖는지 직접 확인해 보세요.

# 디플로이먼트 설정 예시
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-web-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: my-web-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.21
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5

위 예제에서 핵심은 strategy 부분입니다. maxUnavailable: 0으로 설정함으로써, 업데이트 과정 중에도 서비스 가능한 포드 개수가 절대 3개 밑으로 떨어지지 않도록 보장하고 있습니다. 또한 readinessProbe를 설정하여, 새 포드가 단순히 켜지는 것을 넘어 실제 트래픽을 받을 준비가 되었을 때만 기존 포드를 교체하도록 설계했습니다.

STEP 5. 장애 시 즉시 복구하는 롤백(Rollback) 실행

만약 v2 버전 배포가 완료되었는데, 로그를 보니 데이터베이스 연결 오류가 발생하고 있다면 어떻게 해야 할까요? 당황해서 수동으로 포드를 지우는 것은 최악의 선택입니다. 디플로이먼트는 과거의 히스토리를 기억하고 있기 때문입니다.

명령어 한 줄로 이전의 안정적인 상태로 되돌릴 수 있습니다. kubectl rollout undo deployment/web-server-deployment 명령을 사용하면, 시스템은 즉시 이전에 성공했던 레플리카셋을 찾아 다시 배포를 시작합니다. 이것이 바로 디플로이먼트가 제공하는 강력한 안전장치입니다.

이처럼 디플로이먼트를 활용하면 복잡한 배포 과정을 자동화하고, 사람이 실수할 수 있는 영역을 시스템의 영역으로 넘길 수 있습니다. 이제 실제 운영 환경에서 흔히 저지르는 실수들을 통해 더 견고한 운영 노하우를 쌓아보겠습니다.

자주 하는 실수와 해결법

디플로이먼트를 운영하다 보면 설정 오류로 인해 서비스가 엉망이 되는 경우가 종종 발생합니다. 현장에서 가장 빈번하게 발생하는 문제 5가지를 정리했습니다.

  • Selector와 Template의 라벨 불일치
    왜 발생하는가: YAML 작성 시 실수로 `matchLabels`의 이름과 `template.metadata.labels`의 이름을 다르게 적는 경우입니다.
    ✅ 해결법: 반드시 두 라벨이 완벽하게 일치하는지 확인하세요. 일치하지 않으면 디플로이먼트는 포드를 생성해도 관리 대상에서 제외하여 무한 생성 루프에 빠집니다.
  • Readiness Probe 미설정
    왜 발생하는가: 애플리케이션이 뜨는 데 시간이 걸리는데, 쿠버네티스는 컨테이너가 실행되자마자 트래픽을 보내려고 하기 때문입니다.
    ✅ 해결법: 애플리케이션의 준비 상태를 체크하는 `readinessProbe`를 반드시 설정하여, 준비된 포드에만 트래픽이 흐르도록 하세요.
  • Resource Limit 미지정
    왜 발생하는가: 포드가 사용할 CPU와 메모리 한도를 정하지 않으면, 특정 포드가 노드의 자원을 독점하여 다른 포드를 죽이는 현상이 발생합니다.
    ✅ 해결법: `resources.limits`와 `resources.requests`를 명시하여 각 포드가 사용할 자원을 예측 가능하게 관리하세요.
  • 잘못된 Image Pull Policy
    왜 발생하는가: 동일한 태그(예: latest)를 사용하는 이미지를 업데이트했을 때, 쿠버네티스가 로컬에 있는 옛날 이미지를 그대로 사용하기 때문입니다.
    ✅ 해결법: 이미지를 업데이트할 때는 고유한 버전 태그를 사용하거나, `imagePullPolicy: Always` 설정을 사용하세요.
  • Deployment 전략 오설정
    왜 발생하는가: 무중단 배포가 필요한 서비스인데 `strategy.type`을 `Recreate`로 설정하면, 기존 포드를 모두 죽인 뒤 새 포드를 띄우므로 서비스 중단이 발생합니다.
    ✅ 해결법: 서비스 가용성이 중요하다면 반드시 `RollingUpdate` 전략을 선택하세요.
⚠️ 주의
배포 중 장애가 발생했을 때, 단순히 포드를 삭제(delete)하는 것은 문제를 해결하지 못합니다. 반드시 `rollout undo`를 통해 디플로이먼트 차원에서 롤백을 수행해야 합니다.

자주 묻는 질문

Q. Deployment를 삭제하면 실행 중인 포드들도 같이 사라지나요?

네, 그렇습니다. 디플로이먼트는 포드를 관리하는 상위 객체이기 때문에, 디플로이먼트를 삭제하면 그 하위의 레플리카셋과 포드도 함께 삭제 절차를 밟게 됩니다.

Q. 레플리카셋(ReplicaSet)을 직접 생성해서 써도 되나요?

기술적으로는 가능하지만 권장하지 않아요. 레플리카셋은 버전 관리와 롤백 기능을 제공하지 않기 때문에, 대부분의 운영 환경에서는 디플로이먼트를 사용하는 것이 표준입니다.

Q. 무중단 배포가 왜 안 되고 서비스가 끊기나요?

두 가지 가능성이 커요. 첫째는 `strategy`가 `Recreate`로 설정된 경우이고, 둘째는 새 포드가 트래픽을 받을 준비가 되었음을 알리는 `readinessProbe`가 설정되지 않아 준비되지 않은 포드로 트래픽이 유입되었기 때문입니다.

Q. Selector를 바꾸면 어떻게 되나요?
Selector를 변경하는 것은 기존 포드와의 연결 고리를 끊는 것과 같아요. 이 경우 디플로이먼트는 기존 포드들을 관리 대상에서 제외하고, 새로운 Selector에 맞는 포드들을 처음부터 다시 생성하게 됩니다.

Q. 배포 중 포드가 계속 CrashLoopBackOff 상태에 빠져요.

애플리케이션 자체의 설정 오류나 환경 변수 누락, 혹은 자원 부족(OOMKilled)일 확률이 높습니다. `kubectl logs`와 `kubectl describe pod` 명령어로 상세 원인을 파악해야 해요.

안정적인 운영을 위한 마무리

지금까지 쿠버네티스 운영의 심장이라고 할 수 있는 디플로이먼트의 개념부터 동작 원리, 실무 예제까지 모두 살펴보았습니다. 디플로이먼트를 제대로 다루는 능력은 단순히 도구를 사용하는 것을 넘어, 서비스의 가용성을 책임지는 테크리드의 핵심 역량과도 같습니다.

✅ 핵심 요약

  • 디플로이먼트는 포드와 레플리카셋을 관리하는 상위 컨트롤러예요.
  • 선언적 API를 통해 ‘원하는 상태’를 정의하고 시스템이 스스로 유지하게 합니다.
  • Selector 라벨과 Template 라벨은 반드시 일치시켜야 합니다.
  • 무중단 배포를 위해서는 RollingUpdate 전략과 Readiness Probe가 필수예요.
  • 배포 실패 시에는 kubectl rollout undo로 즉시 복구하세요.

오늘 배운 내용을 바탕으로 바로 다음 단계로 나아가 보세요. 이론을 아는 것보다 중요한 것은 실제 클러스터 환경에서 YAML을 적용해 보고, 일부러 오류를 내보며 시스템이 어떻게 반응하는지 관찰하는 것입니다.

실행을 위한 로드맵

  • 오늘 할 일: 간단한 Nginx 디플로이먼트 YAML을 작성하고 클러스터에 배포해 보세요.
  • 이번 주 할 일: 배포 전략을 Recreate에서 RollingUpdate로 바꿔보며 서비스 중단 여부를 직접 테스트해 보세요.
  • 실행 직전 할 일: 실제 운영 환경에 적용하기 전, 반드시 Readiness Probe 설정을 점검하세요.

실습 환경에서 직접 적용해 보시다가, 설정이 꼬이거나 예상치 못한 에러 메시지가 나온다면 주저하지 말고 댓글로 질문을 남겨 주세요. 함께 고민하며 해결해 나가는 과정이 여러분을 더 뛰어난 엔지니어로 만들어 줄 거예요.

관련해서 더 깊이 있는 학습을 원하신다면 쿠버네티스 디플로이먼트 기본 개념 글이나, 전체적인 흐름을 잡을 수 있는 클러스터 구축 입문 글을 함께 읽어보시는 것을 추천합니다.

댓글 남기기