Private Subnet에서 ECS를 구동하기 위해 NAT gateway 사용하기

728x90

Private Subnet에서 배포하면서 생긴 문제


프로젝트 진행 중에 AWS ECS가 생성되지 않는 문제가 발생했다. 현재 프로젝트 설계 구조는 다음과 같이 VPC 내 프라이빗 리소스를 통해 API gateway - Load balancer - Container Service 가 연결되어있는 구조다.




보안상의 이유로 어플리케이션인 ECS에는 외부에서 접속하지 못하게 해야한다. 우리 어플리케이션의 인증/인가는 API gateway와 Cognito에서 이뤄지기 때문에 ECS에는 인증/인가 프로세스가 없기 때문이다. 그래서 허가되지 않은 외부 사용자는 ECS에 접근할 수 없어야 한다.

Private subnet에서 ECS를 생성하려고 하면 딜레이가 발생하다가 생성되지 않는 문제가 발생한다. 이 문제를 해결하기 위해 검색해봤다가 Private subnet에서는 외부 IP로 전혀 접속이 되지 않는다는 것을 알게 되었다. 외부 IP 접속이 되지않으므로 Docker Hub에 있는 이미지를 가져올 수 없던 것이다.

그럼 private subnet이 아닌 public subnet만을 사용해서 ECS를 구동해야하는가? 설계 구조를 바꿔야 하나? 그렇지 않다. Private subnet에 있는 ECS에서 외부 인터넷으로 요청을 보내려면 NAT gateway를 public subnet에 설치하고 ECS의 모든 요청을 public subnet으로 라우팅 시키면 된다. 자세한 내용은 본론을 살펴보자.

ECS 생성 테스트

NAT gateway를 설명하기 앞서 어떤 문제에 직면한 사람이 이 글을 읽으면 좋을지 좀 더 설명하겠다. 아래와 같이 Public subnet 상에서는 ECS 생성에 문제가 없고, Private Subnet에서 ECS가 생성되지 않는 경우에 이 글이 도움이 될 것이다.

Public ECS 생성

 



public subnet을 사용하여 ECS를 생성한다. (private subnet이 함께 포함되어도 상관없다.)

이렇게 public subnet에 ECS를 설치하면 ECS에서 Docker Hub에 접근하여 image를 가져오므로 정상적으로 ECS Task가 실행된다.

 



Private ECS 생성




모든 public subnet의 체크는 해제한다. 오직 private subnet 위에서 ECS를 생성한다. (외부로부터 접근을 차단한다.) 

 

그런데, 아무리 기다려도 Service 및 Task가 제대로 생성되지 않는다. 

 




어찌보면 너무 당연한 것인데, 외부와의 접속을 차단했기 때문에 ECS가 외부 인터넷인 Docker hub에 접근하지 못하기 때문이다. ECS는 생성을 계속 시도하지만 계속 실패하게 된다. (컴퓨팅 자원만 낭비하는 꼴이 된다.)

Private Subnet을 사용한다하더라도 외부와 통신할 통로는 하나 열어줘야 Docker image를 정상적으로 가져올 수 있다. AWS에서는 Private Subnet 상의 컴퓨터가 외부 IP로 접속할 수 있는 방법을 제공해주는데, 그게 바로 NAT gateway다.

NAT gateway 

NAT gateway 란


Public Subnet에 설치하면 Private Subnet에 있는 컴퓨팅 서비스가 라우팅 테이블을 거쳐서 Public subnet으로 요청을 보낼 수 있고, 이 요청은 public subnet에 있는 NAT gateway를 통해 외부 인터넷으로 나갈 수 있다.

NAT gateway 생성


1. VPC 서비스에 들어간다.



2. 왼쪽 탭에서 NAT gateway를 선택한다.

 


3. 오른 쪽에 NAT Gateway 생성을 누른다.

 


4. 이름을 채우고, 서브넷을 연결한다. 서브넷은 해당 서비스가 올라갈 **'Public subnet'** 을 선택해야한다. '탄력적 IP 할당'을 눌러서 탄력적 IP를 새로 생성하거나, 미리 생성해둔 탄력적 IP를 할당한다.

 



5. 'NAT gateway 생성'을 누르면 생성 완료

 

 



6. 이 생성 작업은 public subnet의 개수만큼 생성해줘야한다. (어느 가용영역의 private subnet으로 요청이 전달될지 모르므로 모두 생성해줘야 함. )


## 라우팅 테이블 설정


아직 작업이 끝난 것이 아니다. NAT gateway를 활용하기 위해서는 윗 그림 처럼 private gateway에서 발생하는 요청을 라우팅하여 public subnet에 보내줘야 한다. 그렇게 하기 위해 라우팅 테이블을 설정해줘야 한다.

1. 라우팅 테이블 탭에서 ECS를 올릴 private subnet을 선택한다. 반드시 private subnet을 선택해야 한다.



2. 이미 라우팅 테이블에 몇몇 IP 대상이 등록되어있을 것이다. local은 local로 보낼 용도의 ip이고, 기본적으로 모든 라우팅 테이블에 존재한다. vpce는 vpc endpoint를 의미한다. 



3. 라우팅 추가를 누르고 0.0.0.0/0을 선택한다. (모든 ip에 대한 요청을 의미한다. 특정 ip 라우팅을 추가하지 않는다면 해당 서브넷의 요청은 0.0.0.0/0으로 가게 된다.) 그 옆에 NAT gateway를 선택하면 방금 등록한 NAT gateway 옵션이 나타난다. 해당하는 public subnet의 NAT gateway를 선택하여 연결한다.


4. '변경사항 저장'을 누르면 방금 등록한 라우팅이 테이블에 존재한다. 이렇게 모든 서브넷 private -> public 연결을 해준다.

 

 



private subnet에서 ECS 구동 테스트


다시 ECS로 돌아가 클러스터에서 서비스를 생성한다.



네트워크 부분에서 private subnet만 체크하여 생성한다. 
배포에 성공한다. NAT gateway로 외부 요청 통로를 열어놨기 때문이다.


NAT gateway 사용 시 주의사항


NAT gateway의 비용은 저렴하지 않다고 한다. 이왕이면 NAT gateway를 활용하기보다는 VPC Endpoint를 사용하여 AWS의 서비스를 활용하는 방안을 생각해보자.

예를 들면 Docker Hub에 있는 image 파일을 AWS ECR에 옮겨서 VPC endpoint를 사용하여 접근하여 AWS ECS에서 컨테이너를 생성한다.