무중단 배포

ParkIsComing·2024년 4월 7일

배포

목록 보기
4/4

대표적인 무중단 배포 기법

  1. Rolling 배포
  2. Blue/Green 배포
  3. Canary 배포

Rolling 배포

  • 사용중인 인스턴스 내에서 새 버전을 점진적으로 교체하는 것 (인스턴스를 늘리지 않음!!!)
  • 로드밸런서에서 서비스 중이던 인스턴스로 라우팅 되는 것을 끊고, 인스턴스에 새로운 버전을 적용하여 해당 인스턴스로 라우팅하도록 한다
  • 이를 반복하여 모든 인스턴스에 새 버전의 애플리케이션을 배포한다
  • 장점
    • 인스턴스마다 차례로 배포를 진행하기 때문에 롤백도 간편한다
    • 인스턴스를 추가하지 않아도 된다
    • 최소한의 오버헤드/성능 영향/중단
  • 단점
    • 새 버전을 배포할 때 하나씩 라우팅되는 인스턴스가 줄어들기 때문에 사용중인 인스턴스에 트래픽이 몰릴 수 있다. 따라서 인스턴스별 서비스 처리 용량을 고려해야 된다.
    • 배포가 진행되는 동안에는 구버전과 신버전이 공존하기 때문에 호환성 문제가 발생할 수 있다.

Blue/Green 배포

  • 블루는 구버전, 그린은 신버전을 의미한다
  • 신버전의 인스턴스를 구성한 후 로드밸런스를 통해 모든 트래픽을 한번에 신버전 쪽으로 전환한다.
  • 장점
    • 구버전의 인스턴스가 그래도 남아있어서 손쉬운 롤백이 가능
    • 구버전의 환경을 다음 배포에 재사용할 수 있음
  • 단점
    • 서비스 자원이 두배로 필요하다.
    • 높은 오버헤드

Canary 배포

  • 신버전을 소수의 유저들에게만 배포해보고, 문제가 없는 것이 확인되면 점차 많은 유저들에게 배포하는 방식
  • 블루그린과 유사하나 Canary는 한번에 새로운 인스턴스로 트래픽을 돌리는 것이 아니라, 단계적으로 전환한다.
  • 새로운 배포 버전과 현행 버전을 Prod 환경에서 동시에 검증하고자 할 때 활용
  • 장점
    • 상황에 따라 전환되는 트래픽 양을 조절하며 롤백할 수 있다.
  • 단점
    • 트래픽 제어 부담이 있다.

docker를 이용한 blue-green 배포 적용

Github action으로 CI/CD를 적용할 때, 배포시에 해당 스크립트가 실행되도록 했다.
구체적인 로직은 다음과 같다.

  1. 새로 배포할 때 새로운 버전의 인스턴스(여기서는 도커 컨테이너)를 띄운다.
  2. NginX에서 떠있는 컨테이너를 체크하여(blue or green) upstream을 새로 띄운 컨테이너에 맞는 포트로 연결한다.

deploy.sh

#!/bin/bash
cd /home/ubuntu/app
DOCKER_APP_NAME=jupjup
# blue를 기준으로 현재 떠있는 컨테이너를 체크한다.
EXIST_BLUE=$(docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up)

# 컨테이너 스위칭
# blue가 없으면
if [ -z "$EXIST_BLUE" ]; then
    echo "blue up"
    docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up --build -d
    BEFORE_COMPOSE_COLOR="green"
    AFTER_COMPOSE_COLOR="blue"

# blue가 있으면
else
    echo "green up"
    docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up --build -d
    BEFORE_COMPOSE_COLOR="blue"
    AFTER_COMPOSE_COLOR="green"
fi


echo "Start sleep"
sleep 10
echo "End sleep"

# 새로운 컨테이너가 제대로 떴있는지 확인
EXIST_AFTER=$(docker-compose -p ${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} -f docker-compose.${AFTER_COMPOSE_COLOR}.yml ps | grep Up)

# {EXIST_AFTER}가 있으면
if [ -n "$EXIST_AFTER" ]; then
  echo "nginx reload.."
    #  nginx.config를 컨테이너에 맞게 변경하고 reload
    sudo cp /etc/nginx/nginx.${AFTER_COMPOSE_COLOR}.conf /etc/nginx/nginx.conf
    sudo systemctl reload nginx
  # 이전 컨테이너 종료
  echo "$BEFORE_COMPOSE_COLOR down"
  docker-compose -p ${DOCKER_APP_NAME}-${BEFORE_COMPOSE_COLOR} -f docker-compose.${BEFORE_COMPOSE_COLOR}.yml down
else
    echo "> The new container did not run properly."
    exit 1  
fi

nginx.conf 파일은 nginx.blue.conf와 nginx.green.conf로 나누어 설정했다.
blue, green 각각 upstream을 8081, 8082의 다른 포트로 설정해주면 된다.

nginx.green.conf

http {
// 생략
        upstream jupjup-server {
                server 127.0.0.1:8081 max_fails=3 fail_timeout=10s;
        }

0개의 댓글