Transport Layer는 OSI 7 Layer 중 네 번째에 해당하는 계층입니다. 송신자와 수신자 간의 논리적인 연결을 담당하는 계층이죠. 송신자와 수신자가 데이터를 주고받기 위해서는 연결(Connection, 이하 커넥션)이 필요한데 네트워크 상에 커넥션이 기다란 줄처럼 존재하는 것이 아닌 송신자와 수신자만이 알고 있는 논리적인 존재를 의미합니다. 송신자와 수신자 모두가 알고 있다 보니 마치 네트워크 상에 연결이 존재하는 것처럼 표현하는 것이죠. 그리고 Transport Layer에 소속된 프로토콜 TCP와 UDP는 모두 이 커넥션을 생성하기 위한 역할을 맡고 있습니다.
TCP는 3-way handshake를 통해 송신자와 수신자가 데이터를 주고받기 위한 최적의 상태를 제공합니다. 송신자와 수신자 모두 데이터 송/수신이 가능한 상태인지, 한 번에 보낼 때 얼마나 보낼 수 있는지, 또 받을 때 얼마나 받을 수 있는지를 끊임없이 확인합니다. 또 수신자가 데이터를 받다가 수신자의 Buffer가 넘쳐 일부 데이터를 유실할 경우, 재송신을 요청하기도 합니다. 그만큼 데이터의 온전한 송/수신에 심혈을 기울입니다. 이를 신뢰성 있는 연결(Connection)이라고 부르기도 하죠. 데이터를 온전히, 순서대로 받는 것을 중요하게 여기는 프로토콜은 TCP를 기반으로 합니다.
UDP는 TCP와 다르게 신뢰성 있는 연결을 보장하지 않습니다. 송신자가 수신자에게 데이터를 보내면 제대로 전송되었는지 확인하지 않으며, 데이터를 보낸 즉시 다음 데이터를 송신합니다. 데이터의 순서와 도착 확인 등이 중요하지 않고 빠르고 실시간으로 전달하는 것을 중요하게 여기는 프로토콜은 UDP를 기반으로 합니다.
이러한 TCP와 UDP를 이해하고 활용할 줄 아는 로드밸런서들은 보통 L4 스위치 혹은 L4 로드밸런서라고 부릅니다. TCP의 3-way handshake를 수행할 줄 알거나 UDP의 특성에 맞춰 데이터를 전송할 줄 알죠. 다만 TCP와 UDP의 상위 프로토콜을 이해하지는 못 합니다. 가령 TCP를 사용하는 HTTP, HTTPS, FTP, DNS 등의 프로토콜을 이해하지 못하며, UDP를 사용하는 상위 프로토콜인 DNS, SNMP, DHCP 등을 이해할 수 없습니다. 즉 Transport Layer를 다루는 로드밸런서라 함은 TCP와 UDP를 다루는 로드밸런서라고 할 수 있습니다.
여담으로 이름이 Network Load Balancer이기에 Layer 3인 Network Layer에서 사용하는 로드밸런서로 착각하기 쉽습니다. 하지만 AWS 설명서에서도 설명하고 있듯이 이름이 Network Load Balancer일 뿐 엄연히 Transport Layer에서 사용되는 로드밸런서입니다.
Network Load Balancer는 개방형 시스템 간 상호 연결(OSI) 모델의 네 번째 계층에서 작동합니다.
- 출처 : AWS 설명서 -
Network Load Balancer(NLB)란?
Network Load Balancer는 개방형 시스템 간 상호 연결(OSI) 모델의 네 번째 계층에서 작동합니다. 초당 수백만 개의 요청을 처리할 수 있습니다. 로드 밸런서가 연결 요청을 받으면 기본 규칙의 대상 그룹에서 대상을 선택합니다. 리스너 구성에 지정된 포트에서 선택한 대상에 대한 TCP 연결을 열려고 시도합니다.
- 출처 : AWS 설명서 -
Netowrk Load Balancer(이하 NLB)는 AWS에서 제공하는 4가지 로드밸런서 중 하나로 OSI 7 Layer에서 네 번째 계층에 해당하는 Transport Layer를 다루는 로드밸런서입니다. 위에서 언급한 것처럼 TCP와 UDP를 이해하고 트래픽을 처리할 수 있으며, TLS(SSL Offload)까지 가능한 로드밸런서입니다. 아래 그림의 빨간색 박스가 바로 NLB입니다. TCP와 UDP, TLS를 이해하고 트래픽을 처리할 수 있음을 설명하고 있지요.
<Network Load Balancer 선택화면>
(설정 화면 : EC2 서비스 - 로드밸런서 - 로드밸런서 생성)
OSI 7 Layer에서 네 번째 계층인 Transport Layer를 다룬다는 것은 상위 계층인 Layer 5, 6, 7의 프로토콜을 이해하지 못한다는 것을 의미합니다. Application Load Balancer(이하 ALB)는 Layer 4의 TCP뿐만 아니라 Layer 7의 HTTP, HTTPS, WebSocket를 이해하고 처리할 수 있습니다. 이를 다시 말하면 많은 시스템 리소스를 소모해야 한다는 뜻이죠. 하지만 NLB는 Layer 4 너머의 프로토콜을 이해할 필요 없이 TCP와 UDP만을 이해만 되기에 ALB보다 시스템 리소스 소모가 적을 수밖에 없습니다. 신경 쓸 부분이 적기에 NLB는 ALB보다 더 많은 트래픽 처리가 가능하고 뛰어난 성능을 보장합니다. 이는 위의 NLB 선택 화면에서도 잘 나와있지요.
연결 수준에서 작동하는 Network Load Balancer는 안전하게 초당 수백만 개의 요청을 처리하면서도 극히 낮은 지연 시간을 유지할 수 있습니다.
Network Load Balancer의 주요 특징
TCP/UDP 기반 라우팅
NLB는 TCP와 UDP를 이해할 수 있으며 사용자와 EC2 인스턴스의 논리적인 연결(Connection, 이하 커넥션)이 생성될 수 있도록 돕습니다. 물론 여기에 부하분산 또한 당연히 포함됩니다. 부하분산을 실시함과 동시에 사용자와 EC2 인스턴스의 커넥션을 생성하도록 돕고 자신 또한 커넥션을 가지며 관리합니다. 아래 그림은 NLB의 리스너의 프로토콜을 정의하는 부분을 캡처한 것입니다. TCP, UDP, TCP_UDP, TLS가 있지요.
<NLB 리스너의 프로토콜 선택 화면>
(설정 화면 : EC2 서비스 - 로드밸런서 - 리스너 - 리스너 편집)
TCP의 경우, 사용자와 EC2 인스턴스가 커넥션을 생성하기 위해서 3-way handshake(SYN, SYN/ACK, ACK)를 반드시 실시해야 합니다. NLB는 TCP를 이해하고 있기에 사용자와 EC2의 3-way handshake가 제대로 진행되고 있는지를 확인합니다. 3-way handshake가 정상적으로 진행되었다면 사용자와 EC2 인스턴스 모두 커넥션을 갖게 되고 NLB 또한 커넥션을 생성하여 관리합니다. 또한 커넥션을 보유한 기존 사용자가 아니거나 새로운 요청이 아닌 뜬금없는 Request Packet이 날아올 경우, NLB는 Reset Packet을 날려 이를 거부합니다.
UDP의 경우, 위에서 언급한 것처럼 데이터의 전송/상태 등을 확인하지 않고 요청이 있으면 즉시 전달하는 프로토콜이기에 별다른 협상 과정을 거치지 않습니다. 다만 아무리 사용자와 EC2 인스턴스간 별도의 커넥션이 필요 없다고 하더라도 NLB는 Source IP(사용자)와 Destination IP(EC2 인스턴스)를 관리해야 할 필요가 있기 때문에 커넥션 테이블을 보유하고 있을 거라고 예상합니다.
TCP_UDP의 경우, TCP와 UDP 모두를 사용하는 프로토콜을 부하 분산할 때 주로 사용합니다. 대표적인 예가 DNS입니다. UDP 기반 프로토콜인 DNS는 패킷의 크기가 512bit가 넘어가면 TCP를 사용합니다. 그러니 리스너를 구성할 때 TCP_UDP로 해야 NLB를 통한 원활한 통신이 가능해집니다. DNS가 아니어도 TCP와 UDP 모두를 사용해야 한다면 프로토콜을 TCP_UDP로 지정해야 하지요.
TLS에 대해서는 다음 항목에서 서술하겠습니다.
로드밸런싱 방식
TCP 트래픽의 경우, 로드 밸런서는 프로토콜, 원본 IP 주소, 원본 포트, 대상 IP 주소, 대상 포트, TCP 시퀀스 번호에 따라 흐름 해시 알고리즘을 사용하여 대상을 선택합니다.
UDP 트래픽의 경우, 로드 밸런서는 프로토콜, 원본 IP 주소, 원본 포트, 대상 IP 주소, 대상 포트에 따라 흐름 해시 알고리즘을 사용하여 대상을 선택합니다.
- 출처 : AWS 설명서 -
NLB의 로드밸런싱 방식은 5-Tuple(Source IP Address, Source Port, Destination IP Address, Destination Port, Protocol)을 기반으로 한 Flow Hash Algorithm입니다. TCP는 5-Tuple에 더해 TCP Sequence Number까지 사용하지요. 흐름 해시 알고리즘을 사용하여 부하분산을 하되 5-Tuple의 정보 일치/불일치가 커넥션 생성의 기준이 되는 듯합니다. 그렇기 때문에 5-Tuple의 정보 중 하나라도 다르다면 새로운 요청으로 간주되기 때문에 새로운 커넥션을 생성하기 위해 로드밸런싱을 실시합니다. 개인적인 생각으로 ALB에 비해 로드밸런싱 방식이 모호하고 이해하기 어렵습니다.
고정 IP 제공
NLB의 가장 큰 특징은 고정 IP를 갖는다는 것입니다. Private IP뿐만 아니라 Public IP까지도 고정된 IP로 제공됩니다. IP를 통한 접근 제어를 수행하고자 할 경우, 변하지 않는 IP는 매우 중요한 요소가 됩니다. 반면 ALB는 IP가 끊임없이 변화하기 때문에 ALB의 Public IP를 목적지로 삼아 접근 제어(ACL)를 실시하는 네트워크 장비(ex. 방화벽)에겐 매우 난감한 점이 아닐 수 없습니다.
ALB의 이러한 점을 보완하기 위해, NLB를 ALB의 앞단에 두고 고정된 IP를 제공하는 응용방법이 있습니다. NLB를 내세워 고정된 IP를 목적지로 제공하고 ALB의 IP를 대상그룹으로 삼아 ALB를 통해 로드밸런싱을 실시하는 것이지요. NLB가 고정된 IP를 제공하니 NLB의 Public IP를 목적지로 삼아 접근 제어 정책을 만들기 편리합니다. 그리고 ALB IP의 변화는 CloudWatch, Lambda를 통해 감지/변경한 후 NLB의 대상그룹에 집어넣어 서비스를 유지합니다. 아래 그림과 같이 구성되는 것이죠. 자세한 사항은 그림에 참조된 링크를 확인하시기 바랍니다.
<https://aws.amazon.com/ko/blogs/korea/using-static-ip-addresses-for-application-load-balancers/>
Source IP NAT & Traffic Flow
ALB가 갖지 않는 NLB의 특징은 또 있습니다. 바로 Source IP NAT 미실시와 이로 인한 Traffic Flow의 특이점입니다. 앞서 AWS Application Load Balancer 쉽게 이해하기 #1에서 ALB는 'Proxy Server(이하 프록시 서버)'로서 동작하며 모든 Traffic Flow(이하 트래픽 플로우)는 ALB를 거쳐야 하고 ALB가 EC2 인스턴스로 패킷을 전달할 때 사용자의 IP를 ALB의 Private IP로 Source IP NAT를 실시한다고 말씀드렸습니다. 그러나 NLB는 ALB처럼 트래픽 플로우를 모두 제어하지 않고 Source IP NAT도 실시하지 않습니다.
다시 말해 NLB는 Direct Server Return(이하 DSR)에 가까운 트래픽 플로우를 보여줍니다. DSR에 대해서는 L4 스위치 쉽게 이해하기 #9(2, 네트워크 구성 두 번째)에서 언급한 적이 있지요. 서버가 사용자에게 Response 패킷을 보낼 때 L4 스위치를 거치지 않고 사용자에게 직접 전송한다고 설명했었습니다. 아래 그림을 통해 살펴보겠습니다.
<NLB와 EC2의 구성도>
우선 IP를 먼저 확인해보겠습니다. 사용자의 IP는 172.30.16.252(공유기 내부) / 222.98.37.16(공인 인터넷)이며 NLB의 Public IP는 13.209.27.159, Private IP는 AZ 1 10.0.0.75 / AZ 2 10.0.1.20입니다. 그리고 EC2 인스턴스의 IP는 10.0.0.244죠. ELB와 EC2 인스턴스 모두 Public Subnet에 존재하며 EC2 인스턴스는 AZ 1에만 두었습니다. 이제 트래픽 플로우를 하나하나 살펴보겠습니다.
<사용자와 NLB의 트래픽 플로우>
사용자(172.30.16.252)와 NLB(13.209.27.159)의 트래픽 플로우를 보면 ALB와 별 차이가 없습니다. 3-way handshake와 Request 패킷 역시 NLB의 IP와 통신하는 것처럼 보입니다. 여기까지 봐서는 ALB와 차이가 없군요.
<NLB와 EC2의 트래픽 플로우>
EC2 인스턴스에서 트래픽 플로우를 확인해보면 약간 달라집니다. 3-way handshake를 확인해보면 Source IP가 NLB(13.209.27.159)가 아닌 여전히 사용자(222.98.37.16)입니다. 즉 NLB에서 Source IP NAT를 실시하지 않고 바로 EC2 인스턴스로 패킷이 유입됨을 알 수 있습니다. 그렇다는 것은 EC2 인스턴스가 사용자에게 패킷을 보낼 때 목적지가 NLB IP(13.209.27.159)가 아닌 사용자 IP(222.98.37.16)로 지정됨을 의미합니다. NLB를 거치지 않고 Internet Gateway를 통해 즉시 외부 인터넷으로 나가는 것이죠. 위 패킷에서 SYN/ACK에 해당하는 '[S.]'을 보시면 더 정확히 알 수 있습니다. Source IP가 EC2 인스턴스(10.0.0.244.http)이고 Destination IP가 (222.98.37.16)로 되어있습니다. 이는 3-way handshake뿐만 아니라 이후 오고 갈 트래픽에도 모두 적용됩니다.
이를 통해 얻을 수 있는 이점은 명확합니다. NLB는 Request만을 처리하며 Response는 EC2 인스턴스가 직접 전달하므로 NLB의 트래픽 처리 부담이 훨씬 줄어들 것입니다. 그렇다면 NLB가 갖는 장점에 한층 더 다가갈 수 있겠죠.
연결 수준에서 작동하는 Network Load Balancer는 안전하게 초당 수백만 개의 요청을 처리하면서도 극히 낮은 지연 시간을 유지할 수 있습니다.
마지막으로 대상그룹에서 대상을 등록할 때 인스턴스 형식으로 등록하면 위와 같은 처리방식을 보여주지만 IP로 등록할 경우, NLB의 Prviate IP로 Source IP NAT를 실시합니다. 흔히 말하는 'Full-proxy' 방식이 되는 것이죠. ALB와 동일하게 행동합니다.
보안 그룹
NLB는 ALB와 달리 보안 그룹을 갖지 않습니다. 다시 말해 NLB의 Network Interface(이하 네트워크 인터페이스)에는 보안그룹이 적용되지 않기 때문에 보안그룹을 통한 트래픽 제어가 불가능합니다. AWS 내부의 사정으로 추측됩니다.
SSL 인증서 탑재 가능(TLS)
NLB 또한 ALB처럼 SSL Offload를 실시할 수 있습니다. EC2 인스턴스를 대신하여 SSL Handshake를 실시하여 암호화 통신 협상을 완료하고 암호화 패킷을 주고 받으며, EC2와의 통신에서는 평문을 주고 받습니다. 이를 통해 EC2 인스턴스의 부담을 줄여줍니다.
<SSL Offload를 위한 리스너 포트 설정>
(설정 화면 : EC2 서비스 - 로드밸런서 - 리스너 - 리스너 편집)
먼저 리스너 포트를 TLS로 변경합니다. TLS로 변경하여 사용자와 NLB가 반드시 암호화 통신을 하도록 의무화합니다. TLS의 기본 포트 번호는 443이기 때문에 자동으로 443으로 변경됩니다. 이는 사용자 임의로 바꿀 수도 있지요. 그리고 TLS로 변경하면 아래 그림처럼 SSL 인증서를 탑재하는 부분과 NLB가 사용할 보안정책을 고르는 설정 화면이 나타납니다.그 전에 ALPN(Application-Layer Protocl Negotiation)이라는 설정이 나타나는데요. 사용자와 EC2 인스턴스가 어떤 프로토콜을 사용할 것인지 협상하는 과정을 의미합니다. NLB가 EC2 인스턴스를 대신해 사용자가 사용할 수 있는 프로토콜을 규정하는 것이죠.
<SSL Offload를 위한 인증서 적용>
(설정 화면 : EC2 서비스 - 로드밸런서 - 리스너 - 리스너 편집)
보안 정책을 통해 사용하고자 하는 'Cipher Suite'와 SSL 인증서를 선택하고 편집을 완료하면 됩니다. (Cipher Suite는 사용자와 NLB가 사용할 암호화 통신 프로토콜에 대해 협상하는 것으로 중요한 항목입니다. 자세한 사항은 HTTPS 통신과정 쉽게 이해하기 #4(Cipher Suite, 암호문의 집합)을 확인하세요!). 마지막으로 대상그룹의 EC2 인스턴스들의 포트를 '80'으로 설정해야 합니다. HTTPS 통신(Port 443)은 NLB가 하므로 EC2 인스턴스는 평문 통신만 하면 되기 때문에 대상그룹의 EC2 인스턴스 포트는 '80'으로 설정되어야 하지요.
출처 :
'[AWS] > ROG' 카테고리의 다른 글
[AWS] [활용] SSM&CloudWatch 이용한 윈도 서버 모니터링 (0) | 2022.03.28 |
---|---|
[AWS] CloudWatch Agent 로그 위치 (0) | 2022.03.22 |
[AWS] [Windows] hosts 파일 위치, 수정 방법 (0) | 2022.03.21 |
[AWS] t2.micro 인스턴스가 먹통이 되는 이유? - 크레딧 (0) | 2022.03.21 |
[AWS] Budgets으로 비용 알림 받는 방법 (0) | 2022.03.21 |
댓글