Kubernetes에서의 배포는 아무래도 기존과는 조금 다르다.

왜 필요한지 어떤식으로 해야하는지에 대해

약간의 서론과 함께 시작하고

대표적인 배포 방법을 이론적으로 기록하는 글이 되겠다.

 

일반 배포랑 어떻게 다를까?

 

가장 먼저 컨테이너 환경의 시작은

Container Image 파일에서 시작된다. 중요한것은 Image는 변경이 되지 않는다는 점이다.

이미 실행되고 있는 Image 변경은 불가능하다.

새로운 이미지를 만들고 이를 통해 새 컨테이너를 시작해야하는 점을 베이스로 가지고 있자.

 

Kubernetes의 최소 단위는 Pod 라고 한다.

Kubernetes는 Container Orchestration 도구이다.

즉 관리의 최소 단위라고 생각하면 될 것 같다.

 

목적을 위해 하나의 기능으로 컨테이너 이미지를 만들었다면

kubernetes에서는 이 이미지를 관리하는 용도의 Pod라는 기본 요소를 제공한다.

1개의 Pod는 꼭 한개가 아닌, 여러개의 container를 관리할 수 있다.

 

Pod는 스케줄링, 배포의 최소 단위이다.

컨테이너를 실행하기 위해서는 Pod를 통해야 하며 Pod가 죽으면 해당 Pod에게 관리 되는 컨테이너도 사라진다.

 

그렇다면 수정된 사항, 업드레이드 등의 새로운 버전으로의 배포는 어떻게 진행이 될까.

 

kubernetes의 배포 기본 절차

- 이전 버전 파드 제거

- 새로운 버전 파드 생성

- 생성된 파드 상태 확인

- 파드 생성 실패 시 기존 Pod로 롤백

 

가장 쉬운방법은 수동 방법이다.

kubectl delete pod {pod이름}
kubectl apply -f {변경된 image를 사용하는 pod}.yaml
kubectl describe pods {pod이름}

하지만 시스템이 복잡해지고 관리되어야할 pod가 많아짐에 따라 수동방식은 부담이 된다.

 

또한 이전 서비스와 새로운 서비스 사이의 다운타임과 같이

서비스의 배포 방식에 따라 다양한 배포 시나리오를 고려해야 한다.

 

k8s에는 디플로이먼트(deployment)라는 자원이 있다.

이 디플로이먼트를 통해

Pod들의 업그레이드 부터 롤백까지의 절차를 반복,자동화 할 수 있게 된다.

 

서론이 너무 길었다...

이제 원래 정리하고 싶었던 대표적인 배포 시나리오를 적어본다.

 

1. 롤링 배포

우선 kubectl 커맨드를 통한 롤링배포 방식은 더 이상 지원되지 않는다.

deployment의 yaml파일에 원하는 배포방식을 설정하고 적용한다.

 

장점으로는 무중단(zero downtime)이다. 어떻게 무중단이 될까?

업그레이드 Pod를 1개 만들고 이전버전 Pod를 1개 내린다. 이렇게 한세트씩 진행하는 방식이라고 보면된다.

때문에 기본적으로 대상 Pod는 replicas 2개 이상이 되어야 한다.

 

주의 사항

무중단을 제공하는 점에서 오는 문제이다.

이전 버전과 새 버전의 컨테이너가 동시에 존재하고 서비스된다는 점이다.

두 버전 차이로 인해 발생하게 되는 상황을 고려하고 배포를 진행해야 한다.

 

버전차이에 대한 문제는 당연하게도 무중단방식으로 배포하지 않으면 된다.

디플로이먼트의 yaml 파일에 설정값을 통해 이전버전 Pod를 다 죽이고 새 버전으로 올리게 할 수 있다.

 

2. 블루-그린 배포

블루는 이전버전, 그린은 새 버전을 뜻한다.

방법은 간단하다.

기존에 사용중인 deployment는 그대로 서비스 중인 상태에서

새 이미지를 사용한 다른 deployment를 만든다.

새 deployment가 문제없이 올라왔음을 확인하면

기존 사용사던 서비스가 새 deployment로 트래픽을 돌리는 것이다.

간단하게 service selector를 새 deployment로 변경하면 된다.

 

주의 사항

일시적이지만 2개의 deployment가 동시에 올라와 있는 상태라는 점에서 

그동안 어플리케이션 리소스는 2배가 사용된다는 점이 있다.

 

3. 카나리아 배포

카나리아는 새다. 유독 가스에 민감한 새다. 옛날에 광산에서 작은 새를 통해 미리 감지하는 목적으로 썼다고 한다.

즉, 미리 위험을 감지하기 위한 소수의 Pod를 생성하는 방법이다.

새 이미지를 사용한 deployment를 만든다. replicas는 시범 용으로 작은 수를 설정한다.

그리고 서비스를 통해 일부 트래픽을 작은 deployment로 흘리도록 하는 방법이다.

이 후 신규 버전이 정상임을 확인한다면 replica를 늘리고 기존 pod를 0으로 줄인다.

트래픽을 분산하는데 랜덤으로 하기도 특정 사용자로 분류 하기도 한다.

 

Micro
                   작은
Service
                   서비스
Architecture
                   설계방식

 

말그대로 아주 작은 서비스를 말한다.
큰 몸뚱이 하나를 잘게 쪼개는 것이다. 
단순하게 잘게 쪼개기만 하는것은 아니다.
각각 쪼개진 것들이 혼자서도 잘 돌아 가야한다.

모놀리틱(Monolithic) 아키텍처라고 하는게 기존 큰 몸뚱이 구조라고 할 수 있다.
이 구조에서는 보통 기능들이 서로서로 얽혀있어 결합력이 뛰어나기 때문에
로직,코드 등 무엇인가가 바뀐다면? 그에 영향을 받는것이 많아지게 된다.
당연히 몸뚱이가 크면 클수록 복잡성이 더 커질 것이고,
이 말은 작은 기능하나 추가하는 것도 어려운 상황이 될 수도 있다는 것이다.

잘 만들어진 마이크로 서비스 아키텍처에서는 어떨까?
앞에서 말한것처럼 각 쪼개진 서비스들은 혼자서 잘 돌아 간다는 것이 중요하다.
애초부터 다른 서비스 상관없이 잘 돌아가는 구조로 만들어져 있다면
어떤 기능이 추가되더라도 그 대상 서비스만 영향을 미치게 될 것이다.

먹는걸로 예를 들어볼까

----- 모놀리틱 아키텍처 식당 -----
코스가 나오는 식당이라고 해보겠다.

코스는
    에피타이저
    메인
    디저트
    음료
4개의 구성으로 되어있다.
하나의 코스안에 각 메뉴의 맛이 서로 얽혀 있는 구조.

 
코스의 모든 메뉴는 다 따로 노는 것이 아니다 쉐프가 원하는 맛의 흐름이 있다.
(헛소리 죄송합니다. 예를 들다보니..)

----- 마이크로 서비스 아키텍처 식당 -----
에피타이저 가게
메인메뉴 가게
디저트 가게
음료 가게

각각의 가게가 따로 잘 돌아간다.

 

+ Recent posts