[kubernetes] 쿠버네티스 패턴 - 선언적 배포

박원균·2021년 11월 10일
0

Kubernetes

목록 보기
12/24
post-thumbnail

이 글은 "쿠버네티스 패턴 2020빌긴 이브리안,롤란트 후스지음, 안승규,서한배 옮김 책만, 9791189909123" 책을 기반으로 작성되었습니다.

선언적 배포

선언적 배포 (Declaretive Deployment) 패턴의 핵심은 쿠버네티스의 디플로이먼트의 자원입니다.

디플로이먼트는 컨테이너 그룹의 업그레이드 및 롤백 프로세스를 캡슐화하며 컨테이너 그룹을 반복적이고 자동화된 동작으로 실행할 수 있습니다.

문제

셀프 서비스 방식으로 네임스페이스로 격리된 환경을 제공할 수 있으며 스케줄러를 통해 사용자 개입을 최소화하면서 서비스를 배포할 수 있습니다. 하지만 마이크로 서비스 수가 증가하면 새로운 버전을 지속적으로 업데이트하고 교체하는 부담이 커지게 됩니다.

생각해야하는점

다음 버전으로 서비스 업그레이드는

  • 새로운 버전의 파드를 시작하기
  • 이전 버전의 파드를 안전하게 중지하기
  • 새로운 파드가 성공적으로 시작되었는지 대기 및 확인하기
  • 실패할 경우 이전 버전으로 롤백하기 등이 포함됩니다.

이러한 동작은 일부 다운타임은 허용하지만 동시에 여러 서비스 버전을 실행하지 않는 경우 또는 다운타임은 없지만 업데이트가 진행되는 동안 두 버전의 서비스가 함께 실행되기 때문에 자원 사용이 증가하는 경우, 둘 중 하나의 방식으로 수행됩니다.

이러한 단계를 수동으로 수행하다보면 작업자에 의한 오류가 발생할 수 있으며 적합한 스크립트를 만드는 것도 많은 노력이 필요합니다.

위 방법 모두 릴리스 프로세스에 병목 현상을 야기합니다.

해결책

쿠버네티스는 위 문제를 자동화해놓았습니다.

디플로이먼트 개념을 이용하면

  • 애플리케이션 업데이트 방법
  • 개별 전략 활용
  • 다양한 업데이트 프로세스 조정 등을 기술할 수있습니다.

디플로이먼트가 정확히 수행되기 위해서는 컨테이너가 훌륭한 클라우드 네이티브 일원이 되어야합니다. 디플로이먼트의 핵심은 예측 범위 안에서 파드 세트를 시작하고 중지하는 기능입니다.

이것들이 예상대로 작동하려면 2가지 항목을 충족해야합니다.

  • 컨테이너가 수명주기이벤트를 정확하게 수신
  • 파드가 성공적으로 실행되었는지를 알려주는 정상사태 확인 종단점을 제공

컨테이너가 이 두 영역을 정확하게 커버한다면, 플래폿음 이전 컨테이너를 깨끗하게 종료할 수 있으며 업데이트된 인스턴스를 시작해 이전 인스턴스를 교체할 수 있습니다.

그 다음 업데이트 프로세스의 나머지 부분을 선언적 방법으로 정의해서, 미리 정의된 단계와 예상된 결과를 하나의 원자적 작업으로 실행할 수 있습니다

컨테이너 업데이트 동작 옵션

롤링 배포

내부적으로 디플로이먼트는 세트set 기반 레이블 셀렉터를 지원하는 레플리카세트ReplicaSet를 생성합니다. 또한 디플로이먼트 추상화를 통해 RollingUpdate와 Recreate같은 전략을 사용해 업데이트 프로세스 동작을 구체화할 수 있습니다.

# 롤링 업데이트 전략을 위한 디플로이먼트 설정의 주요 부분
apiVersion: apps/v1
kind: Deployment
metadata:
  name: random-generator
spec:
  replicas: 3			# 3개의 레플리카 선언. 롤링 업데이트를 위해서는 2개 이상의 레플리카가 필요합니다.
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1		# 업데이트동안 일시적으로 지정된 레플리카 수에더해 실행될 수 있는 파드의수 = 4
      maxUnavailable: 1		# 업데이트 동안 사용 불가능하게 될 수 있는 파드의 수. = 2
  selector:
    matchLabels:
      app: random-generator
  template:
    metadata:
      labels:
        app: random-generator
    spec:
      containers:
        - name: random-generator
          image: k8spatterns/random-generator:1.0
          readinessProbe:	# 레디니스(Readiness) 점검은 무중단(zero downtime)을 제공하기 위한 롤링 배포에 매우 중요합니다.
            exec:
              command:
                - "state"
                - "/random-generator-ready" 

RollingUpdate 전략 행동은 업데이트 프로세스 동안 중단이 없음을 보장합니다. 내부적으로 이 디플로이먼트 구현은 새로운 레플리카세트를 생성하고 새로운 컨테이너로 이전 컨테이너를 교체 함으로써 비슷한 동작을 수행합니다.

디플로이먼트 객체를 사용하면 maxSurge,maxUnavailable필드를 통해 초과 파드와 사용 가능한 파드 범위를 제어함과 새로운 컨테이너 생성 비율을 제어할 수 있습니다.

디플로이먼트 객체가 버전 업을 통하여 롤링 업데이트하는 과정을 볼 수 있습니다.

선언적 업데이트 옵션

  • kubectl replace를 사용하여 새로운 버전의 디플로이먼트로 전체 디플로이먼트를 교체합니다.
  • 디플로이먼트를 패치(kubectl patch)나 대화식으로 편집(kubectl edit)해서 새로운 버전의 새로운 컨테이너 이미지를 넣는다.
  • kubectl set image 명령으로 디플로이먼트에 새로운 이미지를 넣는다.

디플로이먼트의 이점

  • 디플로이먼트는 그 상태가 내부적으로 쿠버네티스에 전적으로 관리되는 쿠버네티스 자원 객체입니다.
    전체 업데이트 프로세스는 클라이언트와 상호작용 없이 서버 측에서 실행됩니다.
  • 디플로이먼트의 선언적 특성을 통하여, 배포에 필요한 단계보다는 배포된 상태가 어떻게 보여야하는지를 알 수 있습니다.
    -디플로이먼트 정의는 운영 환경에 배포되기 전에 다양한 환경에서 테스트된 실행 가능한 객체입니다.
  • 업데이트 프로세스는 모두 기록되며 일시 중지 및 계속을 위한 옵션 , 이전 버전으로 롤백을 위한 옵션으로 버전이 지정됩니다.

고정 배포

  • 장점
    RollingUpdate 전략은 업데이트 프로세스 동안 무중단을 보장하는 유용한 방법입니다.

  • 단점
    업데이트 프로세스 동안 두 버전의 컨테이너가 동시에 실행됩니다.

  • 문제
    서비스 컨슈머(consumer)에 문제가 발생할 수 있는데 특히 업데이트 프로세스가 이전 버전과 호환되지 않는 변경 사항을 서비스 API에 도입하고 클라이언트가 이를 처리할 수 없을수 있습니다.

  • 대안
    Recreate 전략은 maxUnavailable 개수를 레플리카와 똑같은 개수로 설정하는 효과가 있습니다. 우선적으로 현재 버전의 모든 컨테이널르 죽이고, 이전 버전의 컨테이너가 축출될 때 모든 신규 컨테이너를 동시에 시작함을 의미합니다. 이 같은 순차적 작업으로 인해, 이전 버전의 모든 컨테이너가 중지도니 상태에서는 다운 타임이 발생하며 들어오는 요청을 처리할 신규 컨테이너는 하나도 없습니다.

두 버전의 컨테이너가 동시에 실행되지 않고, 서비스 컨슈머가 한번에 오직 하나의 버전만 처리가능하도록 단수화됩니다.

블루-그린 릴리스

블루-그린 배포(Blue-Green deployment) 란?

다운타임을 최소화하고 위험성을 줄여서 운영 환경에 소프트웨어를 배포하기위해 사용되는 릴리스 전략입니다.

쿠버네티스의 디플로이먼트 추상화는 쿠버네티스가 어떻게 불변 컨테이너를 한 버전에서 다른 버전으로 변환시키는지를 정의한 기본 개념입니다.

기타 쿠버네티스 기본 요소와 함께 디플로이먼트 기본 요소를 빌딩 블록처럼 활용하여 블루-그린 배포의 고급 릴리스 전략을 구현할 수 있습니다.

단계
1. 이미 실행되고 있는 디플로이먼트를 대체할 그린을 생성
2. 실제로 동작하고있는 블루와 비교하여 문제가 없는지 확인
3. Service selector를 이용하여 그린에 일치시키는 업데이트
4. 블루에 요청이 들어온 모든 트래픽이 처리되면 그린에 할당
5. 블루 컨테이너 자원을 해제

설명
서비스 메시(Service Mesh)나 케이네이티브(Knative) 같은 확장 서비스를 사용하지 않는다면 블루-그린배포는 수동으로 수행되어야합니다. 기술적으로는 아직 어떤 요청도 처리하지 않은 최신 버전의 컨테이너=그린로 두 번째 디플로이먼트를 생성해 실행합니다.이 단계에서는 원래 디플로이먼트의 이전 파드 레플리카=블루가 여전히 실행되며 실제 요청을 처리합니다.

일단 새로운 버전의 파드가 정상적이고 실제 요청을 처리할 준비가 되었다는 확신이 들면, 이전 파드 레플리카에서 새로운 레플리카로 트래픽을 전환합니다. 쿠버네티스에서 이런 동작은 서비스 셀렉터(Service selector)를 새로운 컨테이너로 일치 시키는 업데이트에 의해 수행됩니다.

일단 그린 컨테이너가 모든 트래픽을 처리하면 블루 컨테이너는 삭제될 수 있고 향후 또다른 블루-그린 배포를 위해 블루 컨테이너 자원을 해제됩니다.

카나리아 릴리스

카나리아 릴리스란?

카나리아 릴리스(Canary release)는 이전 인스턴스의 작은 하위집합만 새로운 인스턴스로 교체함으로써 새로운 버전의 애플리케이션을 운영에 유연하게 배포하는 방식입니다.

카나리아 릴리스는 일부 컨슈머만 업데이트된 버전을 사용하게 함으로써 운영에 새 버전을 도입할 때의 위험을 줄여줍니다. 새 버전의 서비스와 소수의 사용자 시험군에게 적용된 방식이 만족스럽다면, 비로소 이전 인스턴스를 모두 새로운 버전으로 교체합니다.
단계
1. 새로운 버전의 신규 파드 생성
2. 기존의 파드를 하나 중지
3. 새로운 버전의 신규 파드와 기존에 서비스되고있는 파드 동시에 서비스 진행
4. 이용자에게 새로운 버전의 파드를 이용하게 하고 문제가 없는지 테스트
5. 문제가 없다면 기존에 존재하던 파드를 새로운 버전의 파드로 업데이트

설명
쿠버네티스에서 카나리아 릴리스 기술은 카나리아 인스턴스로 쓰이는 작은 레플리카 수를 갖는 신규 컨테이너 버전에 대해 새로운 레플리카세트를 생성함으로써 구현할 수 있습니다.

이 단계에서 서비스는 컨슈머 중 일부를 업데이트된 파드 인스턴스로 바로 연결해야합니다. 일단 신규 레플리카세트와 함게 모든 것이 예상대로 작동한다는 확신이 들면, 신규 레플리카세트를 늘리고 이전 레플리카세트를 0개로 줄입니다. 이런 방법으로 제어 가능하면서 실제 사용자에 의해 테스트된 서비스를 점점 증가시켜 실행합니다.

profile
함바라기

0개의 댓글