Kubernetes ‐ 디플로이먼트(Deployment), 서비스(Service) - dnwls16071/Backend_Study_TIL GitHub Wiki

📚 디플로이먼트(Deployment)란?

  • 파드를 묶음으로 관리할 수 있는 기능을 디플로이먼트라고 한다.
  • 디플로이먼트의 장점
    • 파드의 수를 지정하는 대로 여러 개의 파드를 쉽게 생성할 수 있다.
    • 파드가 비정상적으로 종료된 경우, 새로 파드를 알아서 생성해 개수를 유지한다.
    • 동일한 구성의 여러 파드를 일괄적으로 일시 중지, 삭제, 업데이트하기 쉽다.

image

  • 디플로이먼트가 레플리카셋을 관리하고, 레플리카셋이 여러 파드를 관리하는 구조이다.
# spring-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: spring-pod-1
spec:
  containers:
    - name: spring-container
      image: spring-server
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Pod
metadata:
  name: spring-pod-2
spec:
  containers:
    - name: spring-container
      image: spring-server
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8080


---
apiVersion: v1
kind: Pod
metadata:
  name: spring-pod-3
spec:
  containers:
    - name: spring-container
      image: spring-server
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8080
# spring-deployment.yml
apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 3 # 생성할 파드의 복제본 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app'이라는 값을 가진 파드를 선택

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블 (= 카테고리)
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너를 생성할 때 사용할 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 없으면 레지스트리에서 가져온다.
          ports:
            - containerPort: 8080  # 컨테이너에서 사용하는 포트를 명시적으로 표현

📚 서비스(Service)란?

  • 실제 요청을 보낼 때는 각 서버에 균등하게 트래픽이 분배되어야 한다.
  • 그래서 파드 앞단에 알아서 여러 파드에 균등하게 요청을 분배해줄 무언가가 필요한데 쿠버네티스에서는 서비스가 여러 파드에 균등하게 요청을 분배해주는 역할을 수행한다.

📚 서비스(Service)를 활용해 Spring Boot 서버와 통신하기

image

apiVersion: v1
kind: Service

# Service 기본 정보
metadata:
  name: spring-service # Service 이름

# Service 세부 정보
spec:
  type: NodePort # Service의 종류
  selector:
    app: backend-app # 실행되고 있는 파드 중 'app: backend-app'이라는 값을 가진 파드와 서비스를 연결
  ports:
    - protocol: TCP # 서비스에 접속하기 위한 프로토콜
      port: 8080 # 쿠버네티스 내부에서 Service에 접속하기 위한 포트 번호
      targetPort: 8080 # 매핑하기 위한 파드의 포트 번호
      nodePort: 30000 # 외부에서 사용자들이 접근하게 될 포트 번호
  • Service 종류
    • NodePort : 쿠버네티스 내부에서 해당 서비스에 접속하기 위한 포트를 열고 외부에서 접속 가능하도록 한다.
    • ClusterIP : 쿠버네티스 내부에서만 통신할 수 있는 IP 주소를 부여하고 외부에서는 요청할 수 없다.
    • LoadBalancer : 외부의 로드밸런서(ELB 등)를 활용해 외부에서 접속할 수 있도록 연결한다.
  • 디플로이먼트를 사용해서 서버 개수를 쉽게 바꾸기 위해서는 레플리카의 개수를 조절해주면 된다.

📚 서버가 죽었을 때 자동으로 복구하는 Self-Healing 이해하기

jwj@192 demo % kubectl get pods
NAME                                 READY   STATUS             RESTARTS         AGE
spring-deployment-7565bdff49-9gsdb   0/1     Completed          10 (5m18s ago)   26m
spring-deployment-7565bdff49-hntt9   0/1     Completed          10 (5m12s ago)   26m
spring-deployment-7565bdff49-l7qzd   0/1     CrashLoopBackOff   10 (22s ago)     26m
  • 쿠버네티스의 파드 조회 시 RESTARTS 값을 볼 수 있는데 이 값은 파드 내에 컨테이너가 작동하지 않음을 인식하고 컨테이너를 새로 만들어 서버를 재시작 시킨 것을 말한다.
  • 이렇게 쿠버네티스는 파드 내의 컨테이너가 종료되면 자동으로 컨테이너를 재시작시키는 셀프 힐링 기능을 가지고 있다.

📚 새로운 버전의 서버로 업데이트 시키기

$ docker build -t spring-server:1.0 .
  • 빌드된 JAR 파일을 새로운 버전의 이미지로 빌드한다.
apiVersion: apps/v1
kind: Deployment

metadata:
  name: spring-deployment

spec:
  replicas: 5
  selector:
    matchLabels:
      app: backend-app

  template:
    metadata:
      labels: 
        app: backend-app
    spec:
      containers:
        - name: spring-container 
          image: spring-server:1.0 # 새로 업데이트된 이미지
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080