단일 서버에서 도커를 이용해 서비스를 운영중이다. 백앤드 컨테이너는 배포시 별다른 문제가 없었으나 프론트엔드 컨테이너는 재실행시 실제 구동까지 텀이 길어서, 배포 후 일정 시간 502가 리턴되는 문제가 있었다. 이 문제를 NginX
를 활용하여 해결하고자 한다.
NginX
제목에서 작성한 것 처럼 현재 웹 서버로 NginX
를 활용하고 있다. NginX
의 upsteam
을 활용하여 메인 서버는 사실상 중단됐지만 중단되지 않은 것처럼 동작하도록 구현할 것이다.
upsteam이란?
upstream
은 다른 서버로 요청(proxy)을 보낼때 어떤식으로 처리할지 정의한다. 많은 경우 다수의 서버에서 분산처리를 위해서 사용한다.
upstream <NAME> {
ip_hash; // <not require>
least_conn; // <not require>
server <HOST>:<PORT> <...options>;
...
keepalive <number>; // <not require>
}
기본적인 형태는 위와 같다. ip_hash
는 같은 ip에서 온 요청은 같은 서버가 처리할 수 있도록 설정할 수 있는 명령이다. least_conn
는 로드밸런싱에 사용되는 명령이다. 요청이 가장 적은 서버로 요청을 보내도록 한다. keepalive
는 요청의 연결을 유지하는 옵션으로 성능 최적화를 위해 주로 사용된다.
주로 사용되는 server
의 옵션은 다음과 같다.
- weight=
number
- 요청을 보낼때 이 서버는
number
만큼의 가중치를 가진다. (기본값 = 1)
- 요청을 보낼때 이 서버는
- max_fails=
number
- 이 서버가
number
만큼 요청이 실패하면 중단된 것으로 간주한다. (기본값 = 1)
- 이 서버가
- fail_timeout=
time
(ex >3s
)- 이 서버가 중단된 경우
time
만큼 요청을 보내지 않는다. (기본값 = 10s)
- 이 서버가 중단된 경우
전체 옵션이 궁금하시다면 공식문서를 참고하세요.
필자는 위 기능을 이용해 로컬호스트에 백업 컨테이너를 띄우고 메인 컨테이너를 재빌드하여 띄운 후 백업 컨테이너를 중단시키는 방식으로 무중단 배포를 구현하고자 한다. (환경변수 등을 활용하여 백업 컨테이너를 잠시 띄우는게 아니라 그린 블루 배포처럼 번갈아 가면서 운영하는 방식이 좀 더 효율적이라 생각된다.)
upstream feserver {
server localhost:3000;
server localhost:3001;
}
upstream beserver {
server localhost:8000;
server localhost:8001;
}
서버 옵션도 기본값으로 충분하며 다른 명령은 필요하지 않으므로 위와같이 심플하게 작성하였다. 이후 위 upstream
을 서버에 아래와 같이 지정할 수 있다.
server {
...
location / {
proxy_pass http://feserver;
}
}
Docker
우선 백업 컨테이너를 구동시키기 위해서 docker-compose.bak.yml
파일을 생성하였다. 여기서 중요한 점은 실제 컨테이너에서 사용하는 포트와 다른 포트로 지정해 주어야 한다는 것이다. 위 NginX
에서 설정한 것 처럼 실제 컨테이너는 3000
, 8000
포트를 백업 컨테이너는 3001
, 8001
포트를 사용한다.
백업 컨테이너 구동 및 중단
docker-compose -p ${DOCKER_APP_NAME}_bak -f docker-compose.bak.yml up -d --build
위 명령어로 백업 컨테이너를 구동시키자. 기존 컨테이너와 이름이 중복되지 않도록 -p
옵션을 주었다.
docker-compose -p ${DOCKER_APP_NAME}_bak -f docker-compose.bak.yml down
이후 위 명령어로 백업 컨테이너를 중단시키자.
docker-compose -p ${DOCKER_APP_NAME}_bak -f docker-compose.bak.yml up -d --build
sleep 10
docker-compose up -d --build
sleep 10
docker-compose -p ${DOCKER_APP_NAME}_bak -f docker-compose.bak.yml down
필자는 위와같이 스크립트를 작성하여 사용중이다.
Ghost