배포를 자동화하고, 무중단 배포를 구현해보자 (4)

kichan.kim·2023년 9월 5일
0

today-playlist

목록 보기
6/6
post-thumbnail

배포를 자동화하고, 무중단 배포를 구현해보자 (1)
배포를 자동화하고, 무중단 배포를 구현해보자 (2)
배포를 자동화하고, 무중단 배포를 구현해보자 (3)

3편에서 배포 자동화를 구축했고 이제 무중단 배포에 대해 이야기 하려고 한다.

무중단 배포가 필요한 이유는 배포 서버에서 CodeDeploy를 통해 받아온 빌드 파일들을 실행하기 위해 기존 프로세스를 중단하게 되는데 이때 사용자들은 페이지에 접근할 수 없게 되기 때문이다.

무중단 배포를 구현하면 기존 프로세스는 종료하지 않고도 새로운 빌드를 배포 할 수 있다.

원리는 간단하다. 일단 새로운 빌드 파일을 실행할 때 기존 프로세스는 그대로 두고 다른 포트로 실행시킨다. 그리고 리버스 프록시를 하나 두고 이 프록시가 바라보는 포트만 변경해 주면 된다.

나는 프록시 도구로 nginx를 사용하였다. 일단 AWS의 로드밸런서를 통해 443으로 들어오는 요청을 3000번 포트로 전달하게 하였다. 왜 3000번인지는 추후에 설명하겠다. 아래는 443 포트에 달아 놓은 프록시이다.

이렇게 하면 사용자 요청은 HTTPS로 요청받고 내부적으로는 HTTP로 변환되어 들어간다.

그 다음 nginx설정을 통해 3000번으로 들어온 요청을 3001번 혹은 3002번 포트로 보낸다.

http {
    ...

    server {
        include /etc/nginx/conf.d/service-url.inc;
        listen       3000;
        listen       [::]:3000;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        location / {
        proxy_pass $service_url;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

여기서 중요한 점이 proxy_pass 부분이다. 특정 포트로 지정되어 있지 않고, service-url.inc 파일에 존재하는 service_url 값을 넣어주는게 포인트이다. 이제 감이 올 수도 있다. 새로운 배포 파일이 받아지고 스크립트 파일이 실행 될 때 service-url.inc 파일에 접근해서 service_url 변수에 새롭게 배포 할 포트 번호를 넣어주는 것이다.

그리고 nginx를 reload 해 주게 되면 새롭게 배포 된 포트를 바라보게 된다. reload는 0.1초 이내에 완료된다.

젠킨스 Pipeline 스크립트를 보면 ApplicationStart시에 Deploy.sh 스크립트 파일을 실행하도록 되어 있다. 이 안에 service_url 변수를 switch 하고 nginx를 reload하는 switch.sh 파일을 실행하도록 하였다.

#!/bin/bash

PORT=$1  # 첫 번째 매개변수로 전달된 포트 번호

echo "> 전환할 Port: $PORT"
echo "> Port 전환"
echo "set \$service_url http://127.0.0.1:${PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc

echo "> 엔진엑스 reload"
sudo service nginx reload   

전환할 포트를 매개변수로 받아 해당 포트로 3000번으로 받은 요청을 전달한다. 현재 service_url이 3001로 설정되어 있다면 전환할 포트는 3002번이 되고, 3002로 설정되어 있다면 전환할 포트는 3001번이 된다. 아래 스크립트는 전환할 포트 번호를 리턴하는 port.sh 파일이다.

#!/bin/bash

PORT=$(grep 'set $service_url' /etc/nginx/conf.d/service-url.inc | awk -F':' '{print $NF}' | awk -F';' '{print $1}')

if [ "$PORT" == "3001" ]; then
    echo "3002"
else
    echo "3001"
fi

이제 자동 배포와 무중단 배포 모두 완성되었다. 개발자는 메인 브랜치에 Push만 하면 빌드와 배포가 자동으로 진행된다. 빌드와 배포중 발생할 수 있는 휴먼 에러를 줄일 수 있고, 빌드,배포에 사용되는 리소스를 다른 곳에 사용할 수 있다. 시행착오도 많았지만 주어진 환경에서 최선의 결과물을 내는 능력을 기를 수 있었다.

profile
keep going

0개의 댓글