Infra/DevOps

[Github Action] 알리바바 클라우드에 무중단 서버 배포해보기(blue/green)

하우아유두잉 2023. 7. 5. 19:07

 

이전 글에서 알리바바 클라우드에 서버를 배포해 보았다.

2023.06.26 - [Infra/DevOps] - How to deploy service to ECS of Alibaba Cloud.(use github actions)

 

How to deploy service to ECS of Alibaba Cloud.(use github actions)

중국 알리바바 클라우드 ECS에 프로젝트를 빌드&배포 하는 cicd github actions를 작성했다. 기본적으로 배포는 tag로 버전 관리를 했고, tag push를 trigger로 활용했다. 도커 이미지는 기본적으로 ACR에 push

bekusib.tistory.com

 

이번엔 무중단으로 배포를 해보려고 한다.

배포 방식은 Blue/Green을 선택했다.

이유는 이제 서비스 런칭을 앞두고 있고, 예상 고객 수가 많지 않아서 단일 인스턴스에 서버를 구축했다.

작업자 또한 나 혼자라서, 관리 측면에서 여러모로 괜찮다고 판단했다.

 

 

큰 흐름은 다음과 같다.

1. Github로 push 한다.

2. Gilhub Actions가 실행된다.

  a. 프로젝트를 도커로 빌드하고, ACR에 저장한다.

  b. ECS에 배포된다. 배포는 deploy.sh에 따라 진행된다.

 


자 그림 이제 실습 흐름을 정리하고자 한다.

 

1. 서버에 nginx 및 docker 설치

 간단하니 생략하겠다.

 

2. nginx.conf 파일 준비

/etc/nginx/sites-available/로 미리 이동을 시킨다.

nginx.server.green.conf (blue는 포트번호만 바꾸면 된다.)

server {
        listen 9000 default_server;
        listen [::]:9000 default_server;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                proxy_pass http://127.0.0.1:9098; # Blue/Green 포트 번호만 다르다
                proxy_set_header Host $host;
                try_files $uri $uri/ =404;
        }
}

 

3. .github/workflows/cicd.yaml 파일 수정

  a. tags를 push 했을때 실행되도록 함

on:
  push:
    # branches: [main]
    tags: 'test-v[0-9]+.[0-9]+.[0-9]+'

 

  b. deploy에서 docker-compose.yaml 파일 생성 부분 변경

    blue/green으로 포트번호를 분리해 나누었다.

cat > docker-compose.yaml << EOF
            version: "3"
            
            services:
              green-server:
                container_name: green-server
                env_file:
                - .env
                restart: always
                image: ACR주소/도커이미지명:${{ needs.build.outputs.IMAGE_TAG }}
                ports:
                  - "9098:9090"

              blue-server:
                container_name: blue-server
                env_file:
                - .env
                restart: always
                image: ACR주소/도커이미지명:${{ needs.build.outputs.IMAGE_TAG }}
                ports:
                  - "9099:9090"
            EOF

 

4. 배포 쉘 스크립트

 github actions에서 배포 시 진행되는 작업위치에 아래 스크립트로 deploy.sh 파일을 만든다.

#!/bin/bash

IS_GREEN=$(docker ps | grep green-server)


if [ -z $IS_GREEN  ];then	# 현재 배포된 서버가 green-server가 아니라면
  # 도커 이미지 가져와서 실행
  docker-compose pull green-server
  docker-compose up -d green-server

  # 도커 정상 작동 확인
  while [ 1 = 1 ]; do
  sleep 3
  REQUEST=$(curl http://127.0.0.1:9098/health) # green-server는 포트가 9098이다.
    if [ -n "$REQUEST" ]; then
            echo "health check success"
            break ;
            fi
  done;

  # nginx .conf파일 교체
  sudo cp ./nginx.server.green.conf /etc/nginx/sites-available/nginx.server.green.conf
  sudo ln -s /etc/nginx/sites-available/nginx.server.green.conf /etc/nginx/sites-enabled/nginx.server.green.conf
  sudo rm /etc/nginx/sites-enabled/nginx.server.blue.conf
  sudo nginx -s reload
  
  # blue-server 정지
  docker-compose stop blue-server


else	# 반대로 진행
  docker-compose pull blue-server
  docker-compose up -d blue-server

  while [ 1 = 1 ]; do
    sleep 3
    REQUEST=$(curl http://127.0.0.1:9099/health)

    if [ -n "$REQUEST" ]; then
      echo "health check success"
      break ;
    fi
  done;

  sudo cp ./nginx.server.blue.conf /etc/nginx/sites-available/nginx.server.blue.conf
  sudo ln -s /etc/nginx/sites-available/nginx.server.blue.conf /etc/nginx/sites-enabled/nginx.server.blue.conf
  sudo rm /etc/nginx/sites-enabled/nginx.server.green.conf
  sudo nginx -s reload
  
  docker-compose stop green-server
fi

 

5. 실행

git tag test-v0.0.0
git push test-v0.0.0

 

6. 결과

Githbu Actions
docker 실행 확인

 

 

 

 

 

참고사이트

https://mr-popo.tistory.com/230