개인 프로젝트 배포환경을 고민하다가, ALB를 적용한 이야기다. 추가로
본 글에서는 L4과 L7 기본 특징, AWS의 ALB(L7 수준)와 NLB(L4 수준), 각 계층별 로드 밸런서의 Trade-off에 대해 정리해 볼 것이다.
세 챕터로 나눴지만 그 안에서 필요한 이야기를 하느라 추가된 내용이 많다. (TLS handshake, TLS offload 등)
1. L4, L7
사실 본 글에서 다룰 내용은 아니다.
각 계층별 헤더 구조를 이해하고 그 차이에서 오는 계층별 역할을 확실히 이해해야 하기 때문이다.(이것도 나중에 블로그에 다 정리해서 남겨보고 싶은 마음이 있다.)
그래서, 아주 간단하게 L4와 L7의 특징에 대해 살펴볼 것이다. (여기서, L7는 당연히 HTTP 프로토콜을 사용한다.)
1.1 L4
L4는 전송 계층으로, 흔히 알고 있는 TCP/UDP와 관련 있는 계층이다.
TCP/UDP 헤더를 보면 공통적으로 있는 것들 중 바로 port #가 있다.(source port #, dest port #)
즉, L4에서는 들어온 메시지가 어떤 소켓으로 요청이 왔는지 판단하기 위해 port라는 정보가 헤더에 있는 것이다.
1.2 L7
L7는 응용 계층으로, 여기서는 HTTP, HTTPS, FTP 등 관련 있는 계층이다.
본 글에서는 HTTP에 대해 다루기 때문에, HTTP Header, Payload 정보 등을 가지고 있다고 볼 수 있다.
2. AWS의 ALB와 NLB
사실 AWS에서의 ALB, NLB라고는 했지만 그냥 L7에서의 로드밸런싱, L4에서의 로드밸런싱으로 이해하면 된다.
2.1. L4에서의 로드밸런싱
말 그대로 L4 수준의 정보를 가지고 로드밸런싱을 하는 것이다.
L4 수준의 정보가 무엇일까?
여기서 말하고 싶은 L4수준의 정보라는 것은 바로 ip, port 번호이다.
즉, L4 스위치는 IP, 포트 번호를 기반으로 스위칭되는 것이고, 주로 부하분산하는 로드 밸런싱하는 데 사용되는 것이다.
(L4스위치를 다른 말로 L4 로드밸런서라고 하는 것)
2.2. L7에서의 로드밸런싱
이것도 마찬가지 L7 수준의 정보를 가지고 로드밸런싱을 하는 것이다.
L7 수준의 정보는 무엇일까?
잠깐 다른 이야기를 하고 들어가야 한다.
네트워크를 지금 L4, L7과 같이 Layer를 나눠서 설명하고 있다. 즉, 계층적으로 구성되어 있고 각 계층마다 가질 수 있는 정보가 다르다는 것이다.
생각해 보면 L4는 L7에 비해 하위 계층이고, 그렇다는 말은 가지고 있는 정보가 적다는 것이다.
(기본적인 부분이지만 정확히 이해해야 TLS을 L4 수준에서 적용할지, L7 수준에서 적용할 지에 선택하는 데 있어 Trade-Off를 고려할 수 있다.)
예를 들어, TCP 기반으로 이루어진 HTTP 프로토콜을 L4에서는 해석할 수 없다.
즉, L7 로드밸런서는 HTTP, DNS, FTP 등 Application Layer 프로토콜을 다루는 로드 밸런서를 말하는 것이다.
정리하자면 아래와 같다.
L4 로드밸런서와 L7 로드밸런서의 큰 차이는 가지고 있는 정보의 차이이고, 가지고 있는 정보로 적절한 곳으로 부하를 분산시켜 주는 로드밸런서라고 이해하면 된다.
2.3. 그래서, AWS의 ALB와 NLB의 차이는?
위에서 L4, L7 로드밸런서에 대해 알아보았고 이제는 AWS에서 제공하는 ALB와 NLB는 어떤 차이가 있을까에 대해 살펴보자.
2.3.1 NLB
NLB는 Network Load Balancer 이며, L4 로드밸런서 역할을 하는 녀석이다.
로드밸런서 선택화면으로 가면 위와 같이 NLB 설명이 나온다.
- 클라이언트는 요청을 보낸다.
- 리스너는 요청과 일치하는 프로토콜이나 지정된 포트를 기반으로 대상을 선택한다. (예를 들어, TLS:443)
- 일치하는 대상은 트래픽을 수신해서 처리한다.
정리하자면, 로드 밸런서가 요청을 받으면 VPC 내의 대상그룹에서 요청에 맞는 대상을 선택하여 포워딩하는 것이다.
L4 로드밸런서의 리스너만 살펴보고 넘어가자. (리스너는 위 로드밸런서가 수신한 요청에 대해 어떻게 처리할지 정하는 것이다.)
NLB의 리스너의 프로토콜은 위 사진과 같이 네 가지가 있다.
TCP
TCP 요청에 대해서는 당연히 3-way handshake 작업을 수행하여, 로드밸런서와 대상 간에 연결을 맺는다.
예를 들어, EC2 대상과의 연결을 위해 3-way handshake을 통한 커넥션을 맺고 이 커넥션을 관리한다.
UDP
UDP 요청은 당연히 연결지향이 아니기 때문에, 즉시 대상으로 요청을 전달한다.
TLS
TLS는 요청은 TLS offload(SSL offload)를 위한 설정을 하게 된다.
때문에 TLS 프로토콜을 사용하기 위해선, 보안 리스너를 등록해야한다. 그리고, 이 보안 리스너는 인증서 등록이 되어야 한다.
TLS offload에 대해서는 아래 챕터 3에서 정리되어 있다.
2.3.2 ALB
ALB는 Application Load Balancer로, L7 로드밸런서 역할을 하는 녀석이다.
로드밸런서 선택화면으로 가면 위와 같이 ALB 설명이 나온다.
- 클라이언트는 요청을 보낸다.
- 리스너는 HTTP 또는 HTTPS 트래픽 요청을 구분하고, 원하는 대상으로 요청을 전달한다.
정리하자면, ALB의 역할은 HTTP 헤더, HTTP 요청 메서드, source IP, 쿼리 파라미터 등을 나누어서 세부적으로 원하는 대상으로 라우팅 하는 것이다.
3. 각 계층별 로드 밸런서의 Trade-off
사실, 해당 포스팅에서 가장 하고 싶었던 이야기는 이 내용이다.
이 내용을 하기에 앞서 각 계층의 로드밸런서의 특징을 이해해야 하기에 내용을 정리한 것이다.
다시 한번 정리하자면,
- L4 로드밸런서는 L4 수준의 정보를 가지고 역할을 수행하는 녀석
- L7 로드밸런서는 L7 수준의 정보를 가지고 역할을 수행하는 녀석
해당 장에서는 TLS handshake와 TLS offload에 대해 정리하고, L4/L7 로드밸런서의 trade-off에 대해 정리하고자 한다.
(* 3.1은 본 글과 전혀 관련 없는 내용이다.)
3.1 TLS handshake
TLS handshake는 TLS 통신이 시작될 때, 클라이언트와 서버 간에 암/복호화할 키(대칭키)를 얻기 위한 정보를 교환하는 작업이다.
작업 과정을 간단하게 요약하면 아래와 같다.
- 클라이언트는 본인이 지원하는 암호화 알고리즘 목록과 TLS Version 등을 전송한다.
- 서버는 클라이언트가 지원하는 암호화 알고리즘들 중 하나를 선택하고, 자신의 TLS 인증서(공개키 포함)를 클라이언트에게 전달한다.
- 클라이언트는 CA의 공개키를 사용해서 서버의 TLS인증서 복호화 한다.
- 이 복호화를 통해 TLS 인증서가 CA에 의해 발행되었고, 위조되지 않았음을 확인한다.
- 클라이언트는 대칭키를 생성하고, TLS인증서에 포함된 공개키를 사용하여 대칭키를 암호화한다. 그리고 서버로 전달한다.
- 이 대칭키를 통해 데이터를 암호화하여 클라이언트와 서버 간 데이터를 주고받는다.
위와 같은 TLS handshake 과정은 꽤나 부담스러운 작업일 수 있다.(TCP 3-way handshake처럼)
그래서 이 부담을 좀 줄여주기 위해 로드밸런서가 TLS handshake를 수행하고, 다음으로 전달되는 대상 서버에겐 HTTP 프로토콜을 사용하여 평문으로 데이터를 주고받게 해주는 과정을 TLS offload라고 한다. (HTTP의 Keep-alive기능처럼)
3.2 TLS offload
만약 서버에서 직접 가지고 있는 TLS 인증서를 클라이언트에게 전달하게 된다면, 위와 같이 TLS handshake를 서버마다 진행해야 한다.
로드밸런서에게 TLS handshake를 위임함으로써, 리소스 부담을 줄이고 로드밸런서와 각 서버 간에는 평문으로 통신이 가능해진다.
NAT처럼 private ip를 통해 평문으로 데이터를 송수신하는 것이다.
위 과정을 TLS offload라고 하며, AWS에선 L4 로드밸런서인 NLB에서도 지원한다.
(참고: https://aws.amazon.com/ko/elasticloadbalancing/features/#Product_comparisons)
3.3 L4/L7 로드밸런서의 trade-off
위 내용들을 적으면서 몇 번 언급하긴 했다.
바로 장/단점을 비교해 보자.
3.3.1 L4 로드밸런서
- 속도 & 성능
L7에 비해 성능 면에서 상위 레이어의 프로토콜에 대한 이해 없이 L7 로드밸런서에 비해 리소스 소모가 적다.
리소스 소모가 적기에 비교적 더 뛰어난 성능을 가진다.
- 로드밸런싱 제한
달리 말해서 단순한 구성을 가지므로 HTTP 헤더, URL 경로 등 응용 프로토콜의 특수한 요구사항을 처리하기 어렵다.
3.3.2 L7 로드밸런서
- 속도 & 성능
응용 프로토콜을 이해하고 처리해야 하기 때문에, 더 많은 리소스를 필요로 한다.
- 정교한 로드밸런싱
HTTP 헤더, URL 경로 등을 기반으로 라우팅 규칙을 세울 수 있다.
+) 그렇다면 TLS를 L4 로드밸런서에? L7 로드밸런서에?
이 내용에 대해 결정하기 위해 고려해야 할 사항은 매우 많겠지만, 고민해 본 나의 생각은 아래와 같다.
- HTTPS와 같은 복잡하고 정교한 처리를 요구하는 트래픽에 대해서는 L7 로드밸런서가 적합할 것 같다.
- SMTP, FTP와 같은 프로토콜은 L4 로드밸런서로 처리해도 충분하지 않을까 싶다.
(FTP와 SMTP의 구성에 대한 깊은 이해는 없다. 단지 "이러한 기준으로 고려해 볼 수 있지 않을까 "라는 나의 개인적인 생각이다)
SMTP나 FTP의 경우 HTTP처럼 심층적이고 정교하게 라우팅 규칙을 세울 필요가 없다고 생각한다.
즉
- 복잡하고 정교한 처리를 요구하지 않음
- 데이터의 안정성과 무결성을 보장
- ip와 port와 같은 L4 수준의 정보로 라우팅이 가능한 경우
위 세 가지 조건을 만족한다면 L4 로드밸런서에 TLS를 적용하는 것이 적합하지 않을까 생각한다.
p.s 안녕하세요, 혹시 위 글을 보신 분들 중에 마지막 생각에 대한 의견이 있으신 분은 댓글 달아주시면 진심으로 감사드리겠습니다!!! :)
'AWS' 카테고리의 다른 글
AWS - serverless 사용방법 (0) | 2022.02.01 |
---|