본문 바로가기
한화시스템 Beyond SW Camp/데브옵스

[Kubernetes] Deployment

by taeh00n 2025. 3. 18.

Deployment

쿠버네티스에서 애플리케이션을 배포하고 관리하는데 사용하는 객체

Deployment복제본을 관리하고 스케일링, 업그레이드 등 작업을 할 수 있게 도와준다.

 

Deployment의 역할

  • 애플리케이션 상태 유지 : 설정한 복제본 수만큼 항상 해당 수 파드를 유지하려고 한다.
  • 자동화 롤백 및 롤링 업데이트 : Deployment가 버전 업데이트를 쉽게 할 수 있게 도와준다. 롤링 업데이트를 통해 점진적으로 업데이트 하고, 문제 발생 시 자동 롤백을 한다.
  • 파드 상태 관리 : 파드가 삭제되면 Deployment가 자동으로 파드 생성해서 복제본 수를 유지한다.

Deployment로 스프링 서버를 실행하기

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring
spec:
  replicas: 2
  strategy:
    type: Recreate
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      type: backend
  template:
    metadata:
      labels:
        type: backend
    spec:
      containers:
      - name: spring
        image: xogns0518/test:v1
        ports:
        - containerPort: 8080
      terminationGracePeriodSeconds: 5

 

Deployment가 정상적으로 생성되었고 설정한대로 파드도 2개가 생성되었다.

 

서비스를 생성해 접근 가능하게 하기

apiVersion: v1
kind: Service
metadata:
  name: backend-svc
spec:
  selector:
    type: backend
  ports:
  - port: 8080
    targetPort: 8080
  type: LoadBalancer

서비스가 2개의 파드들과 잘 연결이 되었다.

서비스가 생성한 외부 엔드포인트로 접속해보니 정상적으로 작동되는 것을 볼 수 있다.


RollingUpdate

리눅스에서 curl http://10.10.10.122:8080/test/ex 이런식으로 명령어를 치면 화면에 출력되는게 나온다.

#!/bin/bash

while true
do
        curl http://10.10.10.122:8080/test/ex
done

그렇다면 위와같은 bash 파일을 작성하고 실행하면 화면에 출력되는 것이 멈추지 않는 한 계속해서 나올 것이다.

만약 v1이 실행중에 여기서 버전을 업데이트 한다면 서비스에 바로 적용이 될까?

 

시간이 오래 걸리진 않았지만 어느 정도 서비스 연결이 끊기다가 업데이트 버전으로 실행되는 것을 확인할 수 있다. 이렇게 되면 일정 시간동안 사용자들이 서비스를 이용하지 못할 것이다.

 

그 이유는 ReCreate 전략은 기존의 모든 파드를 종료하고, 그 이후에 새로운 파드를 생성하기 때문에 새로운 파드가 생성되기 전 까지의 서비스가 끊기는 것이다.

이번에는 Deployment 전략을 RollingUpdate 방식으로 바꾸고 버전 업데이트를 해보겠다

 

RollingUpdate 방식은 기존의 ReCreate 방식과는 달리 파드가 한 번에 삭제되고 새로운 파드들이 생성되는 방식이 아니라 새로운 파드들이 먼저 생성된 것을 보고 기존의 파드들이 삭제되는 방식이다. 하지만 새로운 파드들이 생성되었는데도 불구하고 여전히 바로 새로운 버전의 프로그램이 실행되고 있지 않다. 그 이유는 프로그램이 샐행되는데에는 어느 정도의 시간이 걸리는데 아직 스프링은 실행되지 않았지만 파드들이 생성되었기 때문에 연결을 시도하기에 연결이 정상적으로 이루어지지 않은 것이다.


Liveness Probe, Readiness Probe, Startup Probe 설정

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-app
  labels:
    type: backend
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0  # 기존 Pod가 제거되기 전에 새로운 Pod가 준비됨
      maxSurge: 1        # 한 번에 추가할 최대 Pod 
  selector:
    matchLabels:
      type: backend
  template:
    metadata:
      labels:
        type: backend
    spec:
      containers:
        - name: spring-app
          image: xogns0518/test:v1
          ports:
            - containerPort: 8080

          # Liveness Probe (컨테이너가 정상 실행 중인지 확인)
          livenessProbe:
            httpGet:
              path: /test/ex
              port: 8080
            initialDelaySeconds: 10  # 앱 시작 후 10초 뒤부터 체크 시작
            periodSeconds: 10        # 10초마다 체크
            failureThreshold: 3      # 3번 실패하면 컨테이너 재시작

          # Readiness Probe (애플리케이션이 준비되었는지 확인)
          readinessProbe:
            httpGet:
              path: /test/ex
              port: 8080
            initialDelaySeconds: 5   # 앱 시작 후 5초 뒤부터 체크 시작
            periodSeconds: 5         # 5초마다 체크
            failureThreshold: 3      # 3번 실패하면 서비스에서 제외

          # Startup Probe (애플리케이션이 완전히 시작되었는지 확인)
          startupProbe:
            httpGet:
              path: /test/ex
              port: 8080
            initialDelaySeconds: 10  # 첫 체크까지 10초 대기
            periodSeconds: 5         # 5초마다 체크
            failureThreshold: 30     # 30번 실패하면 컨테이너 종료 (최대 150초 대기)

 

 

  • Liveness Probe: 컨테이너가 정상적으로 실행 중인지 확인. 실패 시 컨테이너를 재시작
  • Readiness Probe: 애플리케이션이 준비되었는지 확인. 준비되지 않으면 서비스에서 제외
  • Startup Probe: 애플리케이션이 완전히 시작되었는지 확인합니다. 최대 150초 대기 후 실패하면 컨테이너가 종료

RollingUpdate 방식으로 버전 업데이트 한 것을 보면 100% 무중단 배포라고 볼 순 없지만 ReCreate 방식에 비해서는 중단을 최소화한 것을 볼 수 있다.