티스토리 뷰

서론

회사에서 만 2년 동안 격무에 시달리다가 비로소 최근에 여유가 생겨서 토이 프로젝트를 만들어보게 되었습니다.

업무에서 해보지 못한 것들이 항상 아쉬운 느낌으로 남아있어서 제 맘대로 해보고 싶은거 다 해볼 수 있는 놀이터 같은 곳이 있으면 좋겠다는 생각에 시작하게 되었습니다.

 

저는 서비스가 만들어지기에 앞서서 가장 먼저 개발 환경을 만들어두고 싶었습니다.

그래야 간단한 기능 구현들도 모두 프런트 개발자와 같이 확인하면서 만들 수 있기 때문이죠.

그래서 간단한 회원가입이랑 로그인 서비스만 만들어두고 바로 클라우드 인프라를 구성하기로 마음을 먹어버렸습니다.

 

당면한 많은 문제들

먼저 제가 당면한 문제들은 아래와 같습니다

  1. 보안까지 신경쓰면서 클라우드에 배포해본적이 없다
  2. aws에 어떤 서비스들을 띄어야 하는지 하나도 모른다

제가 다니는 회사에서는 쿠버네티스를 사용합니다. 그리고 저는 데브옵스 분들이 만들어놓은 곳에서 온실속의 화초처럼 작업을 했습니다.

처음부터 서버를 실제로 서비스할 정도의 퀄리티로 보안을 지키며 구성하려니 뭐부터 해야할지 모르겠더라구요

 

하지만 늘 그랬듯 주먹쥐고 일어서서 이 문제들을 해결해버렸습니다. 그 과정들을 보여드리겠습니다.

 

큰틀 파악하기

'소규모 서비스 인프라' 라고 검색을 하면 여러 예시들이 나옵니다. 

여러 글들을 흐린 눈으로 훑어보고 대강 중복되는 개념들에서 큰틀을 파악해보았습니다.

  1. VPC(가상 네트워크)안에서 서버 인스턴스들이 띄어진다
  2. 사용자들에게 공개할 영역과 공개하지 않을 영역을 정해서 인스턴스들을 관리해야한다

vpc안에서 여러 서비스들이 구성되고 그 서비스들은 서브넷이라는 네트워크로 구분되어 위치하게 됩니다.

그리고 각각의 서비스들은 서브넷에 따라 퍼블릭이 될지 프라이빗이 될지 결정됩니다.

 

VPC란?

virtual private cloud의 줄임말입니다. 한글로 번역하면 가상사설망이구요.

그럼 왜 가상을 사용하게 된걸까요?

클라우드를 안에서는 여러 서비스들이 물리적으로는 복잡하게 얽혀있습니다. 그래서 논리적(가상)으로 분리해주지 않으면 서비스 인스턴스들 간의 연결 복잡성은 매우 높아져 하나의 인스턴스를 추가하거나 수정하는 경우에도 연쇄적으로 많은 수정을 거쳐야하는 상황이 발생하게 됩니다. 

그래서 논리적으로 사용자 별로 구역을 정해준 것이 VPC입니다. 

 

VPC안에는 서브넷과 라우터, 인터넷 게이트웨이 등등이 존재하게 됩니다.

 

인프라 구성하기

1. 스프링, 디비 인스턴스 위치 정하기

먼저 제가 작업한 스프링을 어디에 띄우나 고민을 했습니다.

근데 생각을 해보니 제가 어떤 서비스를 사용할 때, 포트로 직접 붙어서 api 요청을 해본적은 없는거 같더라구요.

그리고 그렇게 접근하게되면 직접적으로 하나의 서버만을 타게팅해서 디도스 공격 같은걸 할 수 있을거 같아서 위험하겠다 싶었습니다.

따라서 스프링 서버랑 rds는 안전하게 프라이빗 서브넷에 위치시켰습니다. 

스프링과 디비는 기능적으로는 같은 서브넷에 둬도 괜찮을거라 생각이 들긴하지만 같은 라우팅 테이블에 영향을 받는 다는 것이 어색하게 느껴졌습니다.

그리고 스프링과 디비는 서로의 역할과 성격이 다르기에 서브넷을 분리하여 위치시켜야 한다고 생각했습니다.

 

2. 서브넷에 외부 인터넷 연결하기

저는 디비는 rds로 했다가 가격이 부담이 되어 ec2에 mysql을 설치하는 걸로 수정했습니다.

그리고 이때 프라이빗 서브넷에 위치할 ec2에 어떻게 접근해서 mysql을 설치해야하는지 검색해보니 bastion host와 nat gateway을 통해 해결을 할 수 있다는 걸 알았습니다. 

bastion host말고도 aws의 open vpn을 통해서도 해결이 되지만 가능하면 aws의 서비스를 쓰지 않고 ec2를 사용하고 싶었습니다. (지갑 이슈)

같은 이슈로 aws의 nat gateway를 쓰지 않고 nat instance를 사용하였습니다

지금은 필요하지 않은 고가용성을 포기하고 실리를 챙겼습니다.

 

bastion host란?

퍼블릭 서브넷에 위치하여 프라이빗 서브넷에 위치한 ec2에 ssh로 접근을 가능하게 해주는 터널링 호스트

 

nat gateway란?

프라이빗에 위치한 ec2들이 인터넷에 접근하기 위해 사용하는 gateway

인터넷 접근이 필요한 이유

1. open api를 사용하는 경우

2. 필요한 라이브러리를 다운받는 경우

 

저는 퍼블릭 서브넷에 bastion host를 두어 프라이빗 ec2에 ssh로 접근했고 똑같이 퍼블릭 서브넷에 nat instance를 두고 프라이빗 서브넷의 라우팅 테이블에 nat instance를 연결하여 외부 인터넷에 접근 가능하도록 하였습니다. 

아 그리고 마지막으로 가장 중요한 vpc에서의 인터넷 연결을 책임지는 Internet gateway를 추가하였습니다.

3. 도메인 설정하기

이제 클라이언트에서 저의 서비스에 접근할 때 사용할 도메인을 생성하고 연결하려 합니다. 

everydaehwa.net

route53에서 이 도메인을 get했습니다. 

에브리 대화 도메인과 프라이빗 서브넷에 있는 서비스들을 연결해줄 nginx를 선택했습니다. 

aws alb가 있지만 이것도 너무 비싸더라구요.

도메인으로 요청이 오면 nginx가 요청들을 다 받아내서 프런트 화면에 대한 요청은 react서버로 보내고 api 요청은 다시 그 프라이빗에 있는 nginx로 요청이 보내지도록 하였습니다. 

프라이빗 서브넷 안에 다시 nginx를 둔 이유는 부하분산을 위해 scale out에 용이하게 하기 위함이었고 해당 프라이빗 서브넷 외부에서는 한곳만을 바라봐서 그 안의 여러 api 요청을 처리하는 것을 퍼사드스럽게 처리하고 싶었기 때문입니다.

최종적으로 제가 구성한 서버 인프라들은 이렇습니다

마지막으로 보안 그룹을 설정하겠습니다.

저는 항상 잘 동작하게 러프하게 만들어두고 디테일은 마지막에 조금씩 설정하면서 테스트하는게 좋더라구요.

 

4. 보안그룹 설정하기

 

bastion host

Inbound rule
source port
my ip 443 (HTTPS)
22 (SSH)
Outbound rule
source port
0.0.0.0/0 모든 트래픽

ssh는 머신에 ssh로 접근해서 cli를 치기 위해 필요하고

443은 인터넷에 접근해서 필요한 라이브러리들을 다운받기 위해 필요합니다.

 

ALB

Inbound rule
source port
0.0.0.0/0 80 (HTTP)
443 (HTTPS)
Outbound rule
source port
0.0.0.0/0 모든 트래픽

외부 요청을 받을 것이기에 http, https요청만을 허용했습니다

 

Private ec2 (nginx, react)

Inbound rule
source port
bastion host 22 (ssh)
ALB 8080 (tcp)
3000 (tcp)
80 (http)
443 (https)
Outbound rule
source port
0.0.0.0/0 모든 트래픽

bastion에서 접근하기 위해 ssh가 필요합니다.

alb를 통한 서비스 요청을 받기 위해서 tcp 통신이 필요합니다.

필요한 라이브러리와 외부 OPEN API 통신을 하기 위해서 http, https 통신이 필요합니다.

 

DB

Inbound rule
source port
bastion host 22 (ssh)
private ec2 3306 (MySql)
Outbound rule
source port
0.0.0.0/0 모든 트래픽

bastion host에서 접근하기 위해 ssh가 필요합니다.

private ec2(spring)에서 DB 접속을 위해 3306이 필요합니다.

 

정리

이렇게 해서 보안에 안전한 작은 서비스에 적합한 서버 인프라를 구성해보았습니다.

구체적으로 설정하고 만들어가는 걸 보여드리기 보다는 큰 그림과 왜 이렇게 구성했는지를 적는데 중점을 두었습니다.

이거 알아가는데에는 엄청 많은 시간이 걸렸는데 이렇게 글로 정리하려니 글이 생각보다 많이 간략하네요.

시간 내서 읽어주셔서 감사합니다 😃

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함