Print
카테고리: [ Amazon Web Services ]
조회수: 20450

 

쿠버네티스 환경으로 변화하며 다음과 같은 문제들을 접하게 되었다.

   1. 마이크로서비스 수가 점차 증가하며 새로운 버전을 지속적으로 업데이트 및 교체 하는 것에 대한 부담이 증가한다.

      새로운 버전의 파드 시작 -> 이전 버전 파드 중지 -> 새로운 파드가 성공적으로 시작되었는지 대기 및 확인 -> 실패하는 경우 롤백

   2. 작업자에 의한 오류 발생 위험 및 적합한 스크립트 생성을 위한 노력이 많이 든다. 

   3. 릴리스 프로세스에 병목 현상을 야기한다.

      ex. 서로 다른 버전의 서비스 동시 실행 시 자원 사용 증가 

 

이에 따른 해결책이 쿠버네티스의 Deployment 다.

   1. Deployment를 통해 애플리케이션의 업데이트 방법, 개별 전략 활용 등의 기술을 사전에 정의 해놓는다.

   2. Deployment가 예측 가능한 범위 안에서 파드 세트를 시작 및 중지하는 것이 핵심이다.

       이를 위해서는 컨테이너가 수명 주기 이벤트를 잘 수신하는 것, 파드의 정상상태 확인 종단점이 적절하게 제공되어야하는 점이 보장되어야 한다. 

위와 같은 Deployment를 통해 컨테이너 그룹의 업그레이드 및 롤백 프로세스를 캡슐화하며 컨테이너 그룹을 반복적이고 자동화된 동작으로 실행할 수 있게 한다.

 

1. 롤링 배포 - RollingUpdate

  • 내부적으로 Deployment는 set 기반 label selector를 지원하는 ReplicaSet 생성한다.
  • Deployment 추상화를 통해 RollingUpdate (기본값)와 Recreate 같은 전략을 활용하여 업데이트 프로세스 동작을 구체화한다.
  • e.g Deployment for RollingUpdate
apiVersion: apps/v1
kind: Deployment
metadata:
    name: random-generator
spec:
    *replicas: 3*
    strategy: 
        type: RollingUpdate
        rollingUpdate:
            *maxSurge: 1*
            *maxUnavailable: 1*
        selector:
            matchLables:
                app: random-generator
            template:
                metadata:
                    labels:
                    app:random-generator
            spec:
                containers:
                - image: k8spatterns/random-generator:1.0
                  name: random-generator
                  *readinessProbe:*
                    exec:
                        command: ["stat", "/random-generator-ready"]

*replica: 3 => RollingUpdate를 위해서는 2개 이상의 Replica 가 필요. *maxSurge: 1 => 지정된 Replica(3) 수에 더해 실행될 수 있는 파드 수.(총 4개 파드 실행 가능) *maxUnavailable: 1 => 업데이트 동안 사용 불가능한 파드 수. (총2개만 업데이트 시 동시에 사용 가능한 것) *::readinessProbe::: => 무중단 배포를 위해 롤링 업데이트에서 매우 중요한 것!

  • RollingUpdate 전략은 무중단을 보장한다. 새로운 ReplicaSets를 생성하고 새로운 컨테이너로 이전 컨테이너를 교체하는 과정에 Deployment를 사용하여 새로운 컨테이너 생성 비율을 제어함으로써 향상된 기능을 제공하는 것이다.

작동 옵션

  1. $kubectl replace : 새로운 버전의 Deployment로 전체 Deployment를 교체
  2. $kubectl patch 또는 $kubectl edit : 새로운 버전의 새로운 컨테이너 이미지 삽입.
  3. $kubectl set image : Deployment에 새로운 이미지 삽입. (참고) $kubectl rollout : 업그레이드 모니터링 또는 롤백

Deployment의 장점

  1. 전체 업데이트 프로세스가 클라이언트와 상호작용 없이 서버 측에서 실행된다. (오직 쿠버네티스에 의해 전적으로 관리)
  2. 배포된 상태가 어떻게 보여야 하는지 알 수 있다.
  3. 운영 환경에 배포 전에 Deployment 정의를 활용하여 다양한 환경에 테스트 가능하다.
  4. 업데이트 프로세스는 모두 기록되며, 일시 중지, 계속, 롤백에 버전을 활용한다.

2. 고정 배포 - Recreate

  • 업데이트 프로세스 동안 두 버전의 컨테이너가 동시에 실행될 수 밖에 없는RollingUpdate의 단점을 보완 => Service Consumer 문제 발생 가능성 있음.
  • maxUnavailable 개수 == Replica 개수 : 업데이트 동안 기존 버전의 컨테이너는 일단 모두 죽인다.
  • 완전 순차적 작업이므로 이전 버전 컨테이너가 모두 죽은 동안은 다운타임이 필수적으로 발생하며, 들어오는 요청을 처리해줄 컨테이너가 없는 상태가 된다.
  • 두 버전의 컨테이너가 동시에 실행되는 일은 없으며, Service Consumer가 한 번에 오직 하나의 버전만 처리할 수 있다.(단순화)

블루-그린 릴리스 - Blue Green deployment

  • 다운 타임 최소화가 목적

작동 방법

  1. 최신 버전의 컨테이너(Green)로 두 번째 Deployment를 생성해 실행.
  2. 1번은 아직 이전 파드의 Replica가 실행 중인 상태로 실제 요청을 처리 중.
  3. Green이 성공적으로 생성 되었다면 이전 파드 Replica에서 새로운 Replica로 트래픽 전환.(쿠버네티스에서는 이런 동작이 Service selector를 새로운 컨테이너로 일치시키는 업데이트에 의해 수행됨)
  4. Green 컨테이너가 모든 트래픽을 정상 처리 시 Blue 컨테이너 삭제 및 자원 해제

Bule Green Deployment의 장점

Service Consumer에 의해 동시에 여러 버전이 처리되는 복잡성이 감소한다.

Bule Green Deployment의 단점

Blue, Green 컨테이너가 모두 실행되어있는 시간이 필요하므로 애플리케이션 용량이 2배로 필요하다. 업데이트 동안 장기 실행 프로세스 및 데이터베이스 상태 변화로 심각한 문제 발생 가능성이 있다.


카나리아 릴리스 - Canary release

  • 이전 인스턴스의 작은 하위집합만 새로운 인스턴스로 교체하는 방식.
  • “일부” Service Consumer만 새로운 버전의 애플리케이션을 사용하게 함으로써 위험성을 감소시켜준다.
  • 새 버전 서비스 + 소수 사용자 테스트가 완료되었다면 그때 모든 인스턴스를 새로운 버전으로 교체한다.
  • 처음부터 신규 컨테이너 버전에 대해 ReplicaSet을 작게 설정하는 것이 RollingUpdate와의 차이점이다.
  • Service Consumer 중 “일부”만 업데이트된 파드 인스턴스로 바로 연결한다.
  • 테스트 완료 시 신규 버전의 ReplicaSet을 증가시키고 이전 버전의 ReplicaSet을 0으로 만든다.

정리

쿠버네티스의 Deployment는 수동으로 애플리케이션을 업데이트해야하는 프로세스를 자동화된 선언적 동작으로 바꿔주는 역할을 수행한다.

  • 바로 사용 가능한 out-of-the-box 배포 전략 (e.g RollingUpdate, Recreate) => 기존 컨테이너에서 새로운 컨테이너로 교체하는 것을 제어.
  • 릴리스 전략 (e.g. Bull-Green, Canary) => Service Consumer에게 새로운 버전이 제공되는 방식을 제어.

추가적 내용

  • 배포 프로세스에 hook을 활용하여 Pre, Post, custom명령 등을 실행할 수 있게 된다면 배포가 진행되는 동안에도 추가 작업 수행 및 배포 중단, 재시도, 혹은 계속 수행을 명령할 수 있게 될 것이다.
  • 어떤 방식이든 쿠버네티스는 언제 애플리케이션 파드가 실행되는지, 어떤 상태인지 반드시 알아야한다.