[크래프톤 정글 8기] 나만무 2~3 주차 회고

1주 차 회고를 남기고 어느새 2주가 지났다. 2주 간 정말 바쁘게 지나갔다. 2주간 있었던 일들을 전부 담을 수는 없지만 몇 가지 생각나는 것을 기록한다.


EC2 || ECS || EKS

EC2?

우리가 만든 서비스를 배포를 하기 위해 AWS 클라우드 상의 어떤 컴퓨팅 서비스를 사용해서 서버를 배포해야 할까를 많이 고민했다. 처음에는 테스트를 위해 EC2에 많이 올렸다. 초기 채점 서버는 EC2에 있었고 Bastion host 도 실행하고 Rabbit MQ도 별도의 EC2에 있었다. 거기에 우리 메인 서버도 EC2에 올리자니 수동 배포가 너무 걸렸다. 개발하기도 바쁜데 배포를 위해 SSH를 켜고 실행을 하자니 그건 아닌 것 같았다.

EKS?

EKS.. 쿠버네티스 나는 우리 서비스 (프로젝트 수준) 에서 쿠버네티스는 너무 과하다는 생각이 든다. 물론 쿠버네티스를 많이 사용하고 그런 회사가 많다고 생각하지만 팀장으로서 그리고 5주간의 프로젝트를 수행하는 입장에서는 쿠버네티스를 사용하는 것은 욕심이라고 생각한다. 특히 팀 원 전부가 쿠버네티스를 배우려는 것이 아니라면 말이다. 우리 팀도 물론 처음부터 쿠버네티스를 사용하려는 것 은 아니라 MVP를 완성하고 이후의 문제라고 하지만 이제 2주가 남았는데 쿠버네티스 도입이 불가능할 것 같다.

ECS?

ECS 는 컨테이너 이미지로 애플리케이션을 배포하고 관리할 수 있는 컨테이너 오케스트레이션 서비스이다. ECS는 내가 전 직장에서 사용하던 서비스였다. 전 회사는 지금의 프로젝트 보다 개발 인력이 적었다. 그런 상황에서 EC2에 수동 배포를 하기에는 힘들고 빠른 개발을 위해서 ECS를 이용해 서비스 배포를 진행했다. 특히 Fargate를 이용하면 리눅스를 관리할 필요도 없었다. 즉 코드만 개발해서 배포하면 되었던 경험이 있었다.

그래서 우리 팀은 먼저 ECS + Github Action을 이용해 간단한 CI/CD를 구현해서 개발 후의 배포도 챙기려고 했다.


ECS 트러블 슈팅

ECS를 배포하는 과정에 있어 나는 과거 구현 경험이 있으니 다른 팀원이 사용해 볼 수 있도록 옆에서 조언만 하려고 했다. 그래서 도커 파일을 만들고 github action 구성 파일을 만드는 것을 주로 담당했다. 

팀원이 ECS 태스크를 만들고 환경 변수를 설정할 때 DB 접속 정보와 같은 것을 암호화하는 등의 작업을 어떻게 하는지 알려주었다. 하지만 우리가 정의한 태스크가 자꾸 실행이 되지 않았다. 이 것 때문에 몇 시간을 배포하고 테스트를 진행하였다. 그 사이 ECS 태스크 개정 버전이 30은 넘은 것 같다.

하지만 여전히 문제는 해결되지 않았는데 에러를 GPT에 물어보니 네트워크 문제라고 보여진다고 해서 나는 보안 그룹을 확인하거나 Load Balancer를 확인하는 등 원인을 찾으려고 했다. 그리고 원인을 발견했다.

바로 하나의 프라이빗 서브넷이 NAT Gateway 에 연결되어 있지 않은 것이었다. 드디어 의문이 해결되었다. ECS 태스크를 실행할 때 균형적으로 실행시키기 위해 여러 서브넷에 실행을 하는데 현재는 1개의 태스크가 실행 중이었고 배포를 진행할 때에 1개의 태스크가 2번째 서브넷에서 실행이 되는데 이 서브넷에 NAT 가 연결되지 않아서 실행된 태스크가 외부에 트래픽을 보낼 수 없어서 실패했다고 판단을 하고 태스크 배포가 실패해 버린 것이었다. 나중에 들어보니 VPC를 만들었던 팀원이 NAT Gateway가 아닌 NAT 인스턴스를 만들 때 NAT 게이트웨이가 연결되지 않았던 것이었다.


TURN 서버

운영 서버에 배포가 무사히 진행되고 안정화 되었을 때 본격적으로 우리 팀이 구현한 기능들을 배포하고 테스트를 진행하던 중 발견된 문제였다. 로컬에서는 화면 공유 기능이 문제없이 작동하고 잘 동작하는 것을 확인했는데 배포된 서버를 통해 확인해 보니 화면 공유를 했는데 서로의 화면이 표시되지 않고 있었다. 우리는 이 문제가 발견되기 직전의 코드에 문제가 있었나 하고 코드도 살펴보고 로그도 확인했지만 별 다른 문제가 없었다 즉 웹 소켓이나 다른 기능들이 아닌 그 외의 문제가 있다고 보였고 브라우저의 콘솔 로그를 보니 ICE 커넥션에 문제가 있다는 것을 발견했다.

ICE?

Interactive Connectivity Establishment (ICE) 는 브라우저가 peer를 통한 연결이 가능하도록 해주는 프레임 워크로 WebRTC에서는 유저들을 브라우저 간 연결 할 네트워크 인터페이스와 포트를 찾고 바인딩하는 과정에 포함된다고 한다.

  • Peer에 접근 할 때 방화벽을 통과해야 하며
  • 단말에 유일한 주소(public IP)를 할당해야 한다.
  • 라우터가 연결을 차단할 경우 릴레이(우회)해야 한다.

라우터 단에서 직접 연결을 차단 할 경우 데이터를 주고받을 주소를 알 수 없기 때문에 릴레이 서버를 이용하게 되는데 이 서버에는 2가지 종류가 있었다.

STUN 서버와 TURN 서버가 그것이다.

STUN(Session Traversal Utilities for NAT)

클라이언트가 인터넷을 통해 클라이언트의 공개 주소와 라우터의 NAT 뒤에 있는 클라이언트가 접근 가능 여부를 STUN 서버를 통해 확인한다.

NAT 뒷단에 있는 클라이언트는 자신의 공개 주소, NAT 유형 및 NAT가 특정 로컬 포트와 연결한 인터넷 측 포트를 알 수 있다.
이 정보는 클라이언트가 상대방과 UDP 통신을 주고받는 데 사용된다.
STUN 서버는 UDP 포트 3478을 기본으로 가진다.

peer A가 STUN server에 다른 사람과 통신을 하기 위한 public IP를 묻게 되면 STUN 서버는 peer A에게 public IP를 알려준다.

peer B 역시 STUN server에 질의하고 public IP 주소를 받아 peer A와 peer B가 직접 연결된다. 

이 STUN 서버로 구글을 이용했는데 배포 초반에는 그래도 화면 공유가 성공적으로 진행되어 간과했고 WebRTC에 대해 깊게 알지 못한 상태로 급하게 프로젝트 구현을 진행하다 보니 생각하지 못했던 문제가 발생했다.

TURN(Traversal Using Relays around NAT)

STUN 서버가 구글이라지만 모든 것을 해주지 않는다. 만약 상대방의 디바이스가 Symmetric NAT에 있는 경우? 즉 학교가 기업과 같은 곳에서 사용하는 것이 Symmetric NAT라고 한다. 이런 곳에 위치 한 디바이스일 때 각 연결 시도에 대해 서로 다른 공용 IP를 상대 디바이스에 할당할 수 있어 연결에 어려움이 발생할 수 있다고 한다. Peer 간의 IP 주소와 포트 번호를 쉽게 확인할 수 없어 연결할 수 없는 것이다. 

이때 TURN 서버가 Peer와 연결되고 중계를 하여 연결해야 하는 상대 Peer에게 전달한다. 

https://brunch.co.kr/@linecard/156

 

30장. ICE의 이해

1. ICE의 개요 ICE는 Interactive Connectivity Establishment의 약어로 RFC  5245  A protocol for Network Address Translator (NAT) Traversal for Off/Answer Protocols에 정의되었습니다. ICE는 두 단말이 서로 통신할 수 있는 최적

brunch.co.kr

이 블로그 포스팅을 보면 더 잘 이해할 수 있다.


해결 방안

해결 방안은 별게 없다. 그냥 TURN 서버를 만들어야 했다. EC2 하나를 생성하고 그 안에 Coturn이라는 오픈소스 프로그램을 설치하고 설정을 하고 TLS 설정을 위해 인증서를 만들고 연결하는 과정까지 진행했다. 자세한 내용은 추 후에 작성하지 않을까 싶다.


이렇게 2~3 주차가 끝났다. 오늘 멘토링을 진행했는데 모니터링과 관련된 내용을 챙겨보라는 조언을 주셨다. 나도 매우 공감되는 조언이었다. 사실 쿠버네티스 보다 바로 써먹기에는 모니터링 관련된 것이 좋다고 생각된다. 그래서 내일부터는 모니터링, 로깅, 이외에 프로젝트 완성에 목적을 두고 진행할 것이다. 가능하다면 4주 차에 회고를 하고 싶다.