본문 바로가기

백엔드 개발/Docker

[aws lightsail] AWS 라이트세일에 도커 이용해서 운영 서버 구성

반응형

최근 디자이너와 클라이언트 개발자 분들과 협업할 수 있는 기회가 두번 있었다.

그때마다 heroku라는 PaaS 서비스(aws의 elastic beanstalk와 비슷한 무료 서비스)의 Free Plan을 사용했었다.

그런데 헤로쿠의 문제점이 네가지 정도 있었다.

1) 서버의 위치가 미국에 있어서 한국에서 사용하면 성능이 느리다. (데모로 보여주면 눈치 보임..)

2) 30분 동안 서버에 네트워크의 요청이 없을 경우 서버가 멈춘다.

(이떄 스케줄링으로 20분에 한번정도 요청을 보내주면 해결되기 한다.)

3) 무료로 사용할 시 데이터베이스 연동의 어려움(기본으로 제공해주는 RDB의 용량이 5MB였다.)

4) 도커를 써먹을 수 없다. 이건 부차적인 문제이긴하지만 공부한 걸 써먹을 수 있어야...


그래서 평소에 좋다고 익히 들어왔었던 Lightsail을 구매해서 사용하기로 결정했다.

라이트세일을 사용하기로 한 이유는 크게 두가지이다.

1) 저렴하다. 500mb 메모리, 20gb ssd, 트래픽 1TB/month 기준 한달 3.5USD이다.

(기존의 서버 호스팅처럼 서버를 띄우면 한달 요금을 다 결제하는 줄 알았는데. ec2와 비슷하게 인스턴스가 생성되어있는 시간(구동 시간이 아님)을 기준으로 결제를 한다.

한달을 통으로 사용하는 것이 아니라면 인스턴스를 삭제하고 생성하면서 돈을 더 절약할 수 있다!)

2) 기존 ec2처럼 다른 제품들과 연동해서 사용할 수는 없지만 RDS와 로드밸런서, 고정 아이피는 간편하게 설정가능, 스냅샷도 됨됨


aws 회원가입이나 라이트세일 인스턴스 생성과 ssh로 접속해서 docker 설치하는 건 생략한다.

조금만 검색해봐도 좋은 자료가 많다. 주로 공식 사이트를 참고하면 될 듯하다.

내가 운영 서버 구축할 워크 플로와 구성하다가 애먹었던 부분만 다루도록 하겠다.


워크플로우는 간단하다.


우선 데이터베이스(mariadb)와 레디스는 공식 제공되는 이미지를 이용해서 실행한다.


NOTE

-p 옵션으로 port를 연결해주고 내가 연결한 HOST PORT를 Lightsail의 네트워킹 설정의 방화벽 항목에서 개방해줘야한다.

아래와 같이 설정화면에서 포트를 열어주자.
레디스의 경우 외부로 굳이 노출시키지는 않고 있다.


인증서버와 리소스 서버의 경우에는 변경사항이 생겼을 경우에 매번 이미지를 build하고 run 명령어로 이미지를 실행시켜야하는 것이 번거롭다고 생각해서 docker-compose를 이용해서 좀 더 간편하게 배포를 해보기로 한다. 

우선 docker-compose.yml 파일을 작성해서 docker run 명령어를 대체할 수 있다.

yml 파일의 경우 개발용과 실제 사용 환경을 분리해서 작성할 것이다.

큰 차이는 없고 개발용의 경우 jar 파일으로 image 파일을 빌드해서 실행하고, 운영환경에서는 내 docker hub에 push한 이미지를 이용해서 container를 실행할 것이다.

아래는 개발용 yml 파일이다.

version: "3"
services:
resource-server:
build:
context: ./resource-server/
args:
JAR_FILE: ./withkid-resource-server.jar
image: minudev1212/withkid-resource-server:0.5
ports:
- "8081:8081"
expose:
- "8081"
networks:
- withkid_bridge
auth-server:
build:
context: ./auth-server/
args:
JAR_FILE: ./withkid-auth-server.jar
image: minudev1212/withkid-auth-server:0.2
ports:
- "8090:8082"
expose:
- "8082"
networks:
- withkid_bridge
networks:
withkid_bridge:
external: true


간단하게 설명하자면


version은 이 문서의 버전을 명시하는 게 아니라 docker-compose file의 버전이다.

버전은 1, 2, 3 이렇게 있는데 문법이 조금씩 다릅니다. 최신 버전은 3이니 3을 이용했다


resource-server, auth-server는 서비스의 이름이다. 서비스란 실행된 컨테이너 또는 그 구성환경을 이르는 말


build: context 다이렉터리에 존재하는 Docker 파일을 이용해서 이미지를 빌드하기 위한 설정


image: 빌드될 이미지의 파일 명

build: 가 없을 경우 명시된 이미지를 이용해서 컨테이너를 실행


netsorks는 네트워크 설정입니다. 서비스의 하위에 있는 networks 항목은 내가 연결할 네트워크의 이름을 적는다


제일 하위에 networks 설정은 네트워크를 명시해주는 부분

내가 명시한 네트워크의 이름의 존재하지 않으면 생성해준다.

external: true 옵션은 네트워크가 이미 생성되어 있는 경우에 지정하는 옵션이다.


위의 파일을 작성하고 파일이 존재하는 디렉토리에서 docker-compose up --build -d 명령어로 컨테이너 두개를 간단하게 띄울 수 있다.

생성된 컨테이너 명은 [docker-compose.yml이 존재하는 디렉토리명]_[service name]_[Number]으로 생성된다.


생성된 컨테이너는 docker-compose kill이나 docker-compose stop으로 중단시킬 수 있다.



아래는 실제 프로덕션 환경에서 사용하는 yml 파일이다.

version: "3"
services:
resource-server:
image: minudev1212/withkid-resource-server:0.5
ports:
- "8081:8081"
expose:
- "8081"
networks:
- withkid_bridge
auth-server:
image: minudev1212/withkid-auth-server:0.2
ports:
- "8090:8082"
expose:
- "8082"
networks:
- withkid_bridge
networks:
withkid_bridge:


위의 파일과 다른 점은 빌드된 이미지를 불러오기 때문에 build 옵션이 사라졌고 최초 배포 환경이기 때문에 네트워크를 생성해줘야해서 networks 하위의 external 옵션이 사라져있다.

위 파일을 LightSail 인스턴스에 업로드하고 실행해보자.

이 때는 docker-compose up -d 로 실행한다.




NOTE 위에 에러가 뜬 부분이 있는데. 네트워크의 external 설정을 true로 줘버려서 에러가 생겼다.

정상적으로 생성된 것을 알 수 있다.

그리고 최초 네트워크를 생성한 경우에 기존에 실행했던 데이터베이스와 레디스에 docker-compose로 정의한 네트워크를 연결해줘야한다.


docker network connect [네트워크명] [컨테이너명]으로 연결해주자.

경우에 따라서는 기본으로 생성되어 있는 bridge를 없애버리고 docker-compose로 내가 생성된 네트워크만 사용하는 것도 고려해보자.


그리고 방화벽에 포트를 열어줘야한다.

네트워킹 - 방화벽에서 포트를 열어준다.


AWS 라이트세일에서 Docker를 이용한 서버 구성은 이정도로 마치도록 한다.


현재 부족한 점은 자동화 인 것같다.

개선점은 쉘스크립트를 이용해서 처음에 인스턴스를 띄울 떄 서버구성을 자동으로 마쳐주도록 하는 것이다.

빠른 시일내에 이에 관한 글도 작성해야겠다.


반응형