ELB 처음 설정하는 방법, 웹서비스 트래픽을 안정적으로 나누려면 이렇게

얼마 전 작은 웹서비스를 운영하는 지인이 갑자기 접속자가 늘었다며 서버가 자꾸 느려진다고 하소연한 적이 있습니다. 서버 한 대로 버티던 서비스였는데, 이벤트 페이지가 공유되면서 요청이 한꺼번에 몰린 거죠. 이럴 때 가장 먼저 떠올릴 수 있는 구성이 바로 ELB입니다. AWS에서 제공하는 Elastic Load Balancing의 줄임말이고, 여러 서버로 들어오는 요청을 적절히 나눠주는 역할을 합니다.
쉽게 말하면 식당 입구에서 손님을 빈자리로 안내하는 직원과 비슷합니다. 손님이 한 테이블에만 몰리면 오래 기다려야 하지만, 빈 테이블로 잘 나눠주면 전체 흐름이 훨씬 부드러워집니다. ELB도 비슷하게 사용자의 요청을 여러 EC2 인스턴스, 컨테이너, IP 대상으로 분산해 서비스가 한쪽으로 쏠리지 않게 해줍니다.
ELB가 필요한 순간을 먼저 구분하기
처음부터 ELB가 꼭 필요한 서비스도 있지만, 대부분은 트래픽이 늘면서 필요성을 체감하게 됩니다. 서버 한 대에서 웹 애플리케이션과 데이터 처리까지 모두 맡고 있다면 평소에는 문제가 없어 보여도 특정 시간대에 접속이 몰리면 응답 시간이 급격히 늘어날 수 있습니다. 예를 들어 평소 초당 20건 정도의 요청을 처리하던 서비스가 광고나 알림 발송 후 초당 300건을 받게 되면, 서버 CPU와 네트워크가 금방 한계에 가까워집니다.
ELB를 붙이면 요청을 여러 서버로 나눌 수 있고, 특정 서버가 장애 상태가 되면 정상 서버로만 트래픽을 보내는 식의 운영도 가능합니다. 사실 이 부분이 꽤 중요합니다. 단순히 빠르게 만드는 도구라기보다, 서비스가 갑자기 멈추는 상황을 줄여주는 운영 장치에 가깝습니다.
- 접속자가 특정 시간대에 몰리는 서비스
- 서버를 2대 이상으로 늘릴 계획이 있는 서비스
- 무중단 배포나 장애 대응이 필요한 서비스
- HTTPS 인증서를 한 곳에서 관리하고 싶은 서비스
ALB, NLB, GWLB 중 무엇을 고를까
ELB라고 부르지만 실제로는 몇 가지 종류가 있습니다. 웹서비스를 운영한다면 가장 자주 만나는 것은 ALB입니다. Application Load Balancer의 줄임말로, HTTP와 HTTPS 트래픽에 잘 맞습니다. 주소 경로에 따라 요청을 다른 서버 그룹으로 보낼 수 있어서, 예를 들면 /api 요청은 API 서버로 보내고 /admin 요청은 관리자 서버로 보내는 식의 구성이 가능합니다.
NLB는 Network Load Balancer입니다. TCP, UDP 같은 네트워크 계층 트래픽에 강하고, 아주 높은 처리량이나 낮은 지연 시간이 필요한 서비스에서 많이 씁니다. 게임 서버, 실시간 통신, 대규모 내부 시스템처럼 연결 자체의 성능이 중요한 경우에 어울립니다. ALB가 웹 요청의 내용을 보고 똑똑하게 분기하는 쪽이라면, NLB는 빠르고 단단하게 연결을 넘기는 쪽에 가깝습니다.
GWLB는 Gateway Load Balancer입니다. 방화벽, 침입 탐지, 보안 장비 같은 네트워크 가상 어플라이언스를 여러 대로 운영할 때 쓰입니다. 일반적인 블로그, 쇼핑몰, 회사 소개 사이트라면 처음부터 GWLB를 고민할 일은 많지 않습니다. 예전 방식인 Classic Load Balancer도 있지만 새로 구성한다면 보통 ALB나 NLB부터 검토하는 편이 자연스럽습니다.
처음 구성할 때는 대상 그룹과 헬스 체크가 중요합니다
ELB를 만들 때 자주 나오는 개념이 대상 그룹입니다. 대상 그룹은 트래픽을 받을 서버 묶음이라고 생각하면 편합니다. EC2 인스턴스 2대를 같은 대상 그룹에 넣어두면, ELB가 사용자의 요청을 이 두 서버로 나눠 보냅니다. 서버가 더 필요해지면 대상 그룹에 인스턴스를 추가하고, 필요 없으면 빼면 됩니다.
여기서 헬스 체크 설정을 대충 넘기면 운영 중에 은근히 고생합니다. 헬스 체크는 ELB가 각 서버가 정상인지 확인하는 검사입니다. 예를 들어 /health 같은 경로를 만들고, 애플리케이션이 정상일 때 200 응답을 보내도록 구성합니다. 데이터베이스 연결이 끊겼거나 애플리케이션이 멈췄다면 실패 응답을 보내게 만들 수 있습니다.
실무에서는 헬스 체크 간격을 너무 짧게 잡아도 부담이 되고, 너무 길게 잡으면 장애 감지가 늦어집니다. 소규모 서비스라면 10초에서 30초 사이로 시작해 운영 상황을 보며 조정하는 경우가 많습니다. 정상 판단 횟수와 실패 판단 횟수도 함께 봐야 합니다. 실패 1번만으로 서버를 제외하면 순간적인 네트워크 흔들림에도 트래픽이 빠질 수 있고, 실패 횟수를 너무 높이면 실제 장애 대응이 늦어질 수 있습니다.
HTTPS와 비용까지 같이 생각하기
ELB를 쓰면 HTTPS 설정도 훨씬 깔끔해집니다. 서버마다 인증서를 설치하는 대신, 로드 밸런서에 인증서를 연결하고 뒤쪽 서버에는 내부 통신을 맡기는 식으로 구성할 수 있습니다. 물론 보안 요구가 높은 서비스라면 ELB와 서버 사이도 HTTPS로 묶을 수 있습니다. 중요한 건 인증서 갱신과 적용 위치를 단순하게 가져가는 것입니다.
비용도 그냥 지나치면 안 됩니다. ELB는 생성해두기만 해도 시간 단위 비용이 생기고, 처리량이나 연결 수에 따라 추가 비용이 붙을 수 있습니다. 개발용 테스트 환경에서 며칠만 쓰고 지우지 않은 로드 밸런서가 한 달 뒤 청구서에 남아 있는 경우도 꽤 흔합니다. 운영용과 테스트용을 태그로 구분하고, 쓰지 않는 리소스는 주기적으로 확인하는 습관이 좋습니다.
처음에는 ALB 하나에 EC2 두 대, 대상 그룹 하나, 헬스 체크 경로 하나 정도로 단순하게 시작해도 충분합니다. 이후 트래픽이 늘면 오토 스케일링을 붙여 서버 수를 자동으로 늘리고 줄일 수 있습니다. 로그 분석이 필요하면 접근 로그를 남기고, 보안이 중요하면 보안 그룹과 웹 방화벽 설정까지 이어서 다듬으면 됩니다.
초보자가 자주 놓치는 설정
ELB를 만들고도 접속이 안 되는 경우가 있습니다. 이때는 대부분 보안 그룹, 서브넷, 대상 그룹 상태 중 하나에서 문제가 납니다. 로드 밸런서의 보안 그룹은 사용자의 80번 또는 443번 요청을 받아야 하고, 서버의 보안 그룹은 로드 밸런서에서 오는 트래픽을 허용해야 합니다. 서버를 외부에 직접 열어두는 방식보다 로드 밸런서만 외부 요청을 받고 서버는 내부에서만 받도록 구성하면 관리가 쉬워집니다.
또 하나는 리다이렉트입니다. HTTP로 들어온 요청을 HTTPS로 보내고 싶다면 ALB 리스너 규칙에서 처리할 수 있습니다. 애플리케이션 코드에서 억지로 처리할 수도 있지만, 로드 밸런서에서 처리하면 여러 서버에 같은 코드를 반복 적용하지 않아도 됩니다. 경로 기반 라우팅도 마찬가지입니다. 기능이 늘어날수록 규칙 이름과 우선순위를 알아보기 쉽게 관리하는 편이 나중에 덜 헷갈립니다.
ELB는 처음 보면 설정 항목이 많아서 복잡하게 느껴집니다. 그런데 실제 운영 관점에서 보면 역할은 꽤 분명합니다. 사용자의 요청을 받아 정상 서버로 보내고, 장애 서버는 잠시 제외하며, HTTPS와 라우팅을 앞단에서 관리해주는 장치입니다. 작은 서비스라도 서버가 두 대 이상이 되는 순간부터 ELB를 붙여두면 마음이 꽤 편해집니다. 트래픽이 많아진 뒤 급하게 붙이는 것보다, 여유 있을 때 한 번 구성해두는 쪽이 운영하는 사람 입장에서는 훨씬 덜 피곤합니다.
