2023.08.07 - [웹개발] - [docker] fastapi + nginx 블루 그린 배포(무중단배포)[2]

 

[docker] fastapi + nginx 블루 그린 배포(무중단배포)[2]

2023.08.07 - [웹개발] - [docker] fastapi + nginx 블루 그린 배포(무중단배포)[1] 이전편에 이어서 github actions에서 workflow 코드를 공유하겠다. 이전 nginx 설정편을 보고 싶다면 위의 링크를 참고 부탁드린다.

tjjourney7.tistory.com

이전 글에 이어서 deploy관련 sh 스크립트와 docker compose 설정파일에 대해서 설명하겠다.

우선 들어가기 앞서 docker와 docker compose가 설치되어 있지 않다면 배포 대상서버에 설치하길 바란다.

#!/bin/bash
IS_GREEN=$(docker ps | grep green) # 현재 실행중인 App이 blue인지 확인합니다.

if [ -z $IS_GREEN  ];then # blue라면

  echo "### BLUE => GREEN ###"

  echo "1. get green image"
  docker compose pull green # green으로 이미지를 내려받습니다.

  echo "2. green container up"
  docker compose up -d green # green 컨테이너 실행

  while [ 1 = 1 ]; do
    echo "3. green health check..."
    sleep 3

    REQUEST=$(curl http://127.0.0.1:8080) # green으로 request
      if [ -n "$REQUEST" ]; then # 서비스 가능하면 health check 중지
        echo "health check success"
        break ;
      fi
  done;

  echo "4. reload nginx"
  sudo cp -p /etc/nginx/nginx-green.conf /etc/nginx/nginx.conf || exit 1
  sudo sudo systemctl restart nginx || exit 1

  if [ "$(docker ps -q -f name=blue)" ]; then
    echo "5. blue container down"
    docker compose stop blue
  fi
  
else
  echo "### GREEN => BLUE ###"

  echo "1. get blue image"
  docker compose pull blue

  echo "2. blue container up"
  docker compose up -d blue

  while [ 1 = 1 ]; do
    echo "3. blue health check..."
    sleep 3
    REQUEST=$(curl http://127.0.0.1:8081) # blue로 request

    if [ -n "$REQUEST" ]; then # 서비스 가능하면 health check 중지
      echo "health check success"
      break ;
    fi

  done;

  echo "4. reload nginx"
  sudo cp -p /etc/nginx/nginx-blue.conf /etc/nginx/nginx.conf || exit 1
  sudo sudo systemctl restart nginx || exit 1

  if [ "$(docker ps -q -f name=green)" ]; then
    echo "5. green container down"
    docker compose stop green
  fi

fi

위의 로직을 설명하면 이렇다.

1) green 컨테이너가 실행되고 있다면 blue 컨테이너를 실행

2) nginx port를 blue로 바라보게 copy

3) green 컨테이너를 다운시킨다.

4) blue 컨테이너가 실행되고 있다면 위의 로직을 반대로 설정

 

이렇게 하면 사용자는 nginx가 restart되는 아주 찰나의 시점을 제외하고는 무중단으로 홈페이지를 사용할 수 있게 된다.

위의 스크립트에서 nginx 없이 아래와 같이 시도해보았지만 중단 시간이 5초 이상으로 생각보다 길었다.
1) green 컨테이너가 실행되고 있으면 green 컨테이너를 다운

2) blue 컨테이너 실행

3) blue 컨테이너가 실행하고 있으면 blue 컨테이너 다운

4) green 컨테이너 실행

 

따라서 더 짧은 중단시간을 위해 nginx가 필요한 것이다.

이를 위해 docker compose 파일(docker-compose.yml)은 아래와 같다.

version: '3.3'
services:
  green:
    container_name: green
    image: jaypark/image
    ports:
      - "8080:8080"

  blue:
    container_name: blue
    image: jaypark/image
    ports:
      - "8081:8080"

위 코드에서도 짧지만 정말 많은 시행착오를 겪었다.

1. 우선 version: '3.3' 부분은 본인이 설치한 docker compose 버전에 호환되게 넣어줘야 한다. 그렇지 않으면 에러가 발생한다.

2. 줄간격 맞추는 부분도 정확하게 해야지 에러가 발생하지 않는다.

3. image: jaypark/image 부분은 본인의 docker hub repository 명을 넣어야 한다. 그렇지 않으면 에러가 발생한다.

4. ports: 부분은 8081:8080으로 설명하자면 docker container의 외부 port는 8080이며, 내부적으로 사용되는 호스트포트는 8081이란 의미이고, 이 둘을 연결한다고 보면 된다.

지난번 포스트에서 nginx를 80 port로 listen하고 green, blue에 맞게 호스트 port를 각각 8080, 8081로 연결하기 때문에 외부 요청이 블루 그린배포시 다른 포트로 들어올 수 있다. 이 부분이 정말 헷갈렸다...

 

반응형

+ Recent posts