Amazon Web Service Network 쉽게 이해하기

AWS Network Load Balancer 쉽게 이해하기 #2

네트워크 엔지니어 환영 2024. 3. 2. 16:34
반응형

지난 문서에 이어 NLB에 대해 계속 이야기하도록 하겠습니다. 이 문서에서는 NLB의 구성 요소인 리스너와 대상그룹 그리고 기타 기능에 대해 설명합니다.

 

Network Load Balancer의 구성 요소

NLB는 크게 리스너(Listener)와 대상 그룹(Target Group)으로 구성됩니다. Application Load Balancer(이하 ALB)에서는 3가지 요소(리스너, 규칙, 대상 그룹)로 나뉜다고 말씀드렸는데 NLB는 2가지뿐이죠. 앞서 AWS Network Load Balancer 쉽게 이해하기 #1에서 말씀드린 것처럼 NLB는 ALB처럼 HTTP와 HTTPS를 활용하는 것이 아닌 Layer 4 프로토콜인 TCP, UDP를 이용한 부하분산을 실시합니다. Layer 7 프로토콜은 Application Layer라는 이름답게 접속 대상에 대한 정보를 보유하고 있어 라우팅 정책을 이용할만한 요소를 다수 갖추고 있지만 Layer 4 프로토콜(TCP, UDP)은 접속 대상에 대한 연결의 신뢰성 여부를 중시하는 프로토콜인 만큼 TCP, UDP 자체에 대한 라우팅 요소를 갖고 있진 않습니다. 이에 대한 자세한 내용은 L4/L7 로드밸런싱 쉽게 이해하기를 참조하세요.

리스너(Listener)

NLB의 TCP와 UDP 리스너

(설정 화면 : EC2 서비스 - 로드밸런서 - 리스너)

NLB의 리스너는 TCP 혹은 UDP, TLS를 사용하는 요청을 받아들여 이를 대상그룹으로 라우팅(부하분산)할 수 있습니다. 정확히는 TCP와 UDP, TLS의 동작방식을 이해하고 처리할 수 있음을 의미합니다. 한편으로 ALB와 다르게 리스너가 단조로운 모습을 하고 있죠. ALB처럼 HTTP Header(이하 헤더)를 이용하여 다양한 라우팅을 하는 것이 아닌 TCP와 UDP, TLS를 이해하고 원활하게 통신이 가능하는 역할만 하기 때문에 ALB의 리스너처럼 다양한 기능을 보유할 이유가 없습니다. 다시 말해 TCP, UDP, TLS의 헤더를 분석하여 라우팅을 하지 않는다는 뜻입니다. 물론 AWS Network Load Balancer 쉽게 이해하기 #1에서 언급한 것처럼 AWS ACM(SSL 인증서)를 탑재하여 SSL Offload를 실시하는 특별한 기능을 수행할 수 있습니다.

대상 그룹(Target Group)

NLB의 TCP 활용 대상 그룹

(설정 화면 : EC2 서비스 - 대상그룹)

대상 그룹은 리스너가 전달한 요청을 처리할 EC2 인스턴스들의 집합입니다. 정해진 프로토콜(TCP, UDP, TLS)을 처리할 수 있는 EC2가 소속될 수 있죠. 위 사진의 붉은색 박스에서 "프로토콜:포트"의 값이 "TCP:80"인 것을 확인할 수 있는데요. 이 대상 그룹에는 TCP를 이해할 수 있고 80번 포트가 오픈되어 있는 인스턴스만이 속할 수 있음을 의미합니다. 여기에 한 발 더 나아가 로드밸런서 리스너의 포트번호(TCP/8080)와 대상 그룹의 포트번호(TCP/80)를 다르게 설정할 수 있습니다. 이렇게 설정하게 되면 리스너(TCP/8080)에서 대상 그룹(TCP/80)으로 요청이 전달될 때, 목적지 포트번호가 TCP/8080에서 TCP/80으로 변경됩니다. 리스너와 대상 그룹의 포트를 다르게 하여 대상 그룹의 포트를 감출 수 있겠지요. 

(설정 화면 : EC2 서비스 - 대상그룹 - 상태 검사)

ALB의 대상그룹처럼 NLB도 Health Check(이하 헬스 체크)를 실시합니다. 위 사진의 붉은색 박스에서 "상태 검사" 항목에서 확인할 수 있죠. NLB는 헬스 체크를 위해 TCP, HTTP, HTTPS 3가지 프로토콜을 활용합니다. 대상 그룹에 소속된 EC2가 정상 동작 중인지 확인하기 위해 3가지 프로토콜을 활용할 수 있다는 의미이고 각 프로토콜이 갖는 특징(3-way handshake, HTTP Response Code 등)을 활용해 EC2의 상태(Health)를 검사(Check)할 수 있습니다.

대상 그룹의 프로토콜이 UDP라면 헬스 체크를 어떻게 할까요? UDP 역시 헬스 체크를 위해서는 TCP, HTTP, HTTPS 3가지 프로토콜을 사용해야 합니다. UDP는 연결의 신뢰성보다는 데이터 전달의 신속성을 염두에 두고 설계된 프로토콜인 만큼 TCP와 달리 전송한 데이터가 제대로 전달되었는지 확인하지 않죠. 그렇기에 TCP의 3-way hanshake처럼 연결 생성을 위한 사전 연결 과정이 없고 이를 이용한 헬스 체크 방식 또한 존재하지 않습니다. 이런 점을 감안해 봤을 때, UDP를 사용한다 할지라도 포트의 상태를 TCP / HTTP / HTTPS로 체크하여 포트의 오픈 상태를 검사할 목적으로 3가지 프로토콜을 그대로 활용하도록 둔 것으로 보입니다. 헬스 체크 포트에 문제가 생겼다면 TCP / UDP든 응답하지 않을 테니 이를 염두에 두고 TCP 등의 프로토콜로 헬스 체크를 하는 것이죠. 여담으로 On-premise(이하 온프레미스)에서는 UDP 헬스 체크를 위해 ICMP를 곁들어 사용하기도 합니다. ICMP는 목적지에서 응답이 없을 때, "ICMP port unreachable message"를 되돌려 보내기 때문이죠.  

마지막으로 대상 그룹에 들어갈 대상 유형(Target Type)을 "인스턴스" 혹은 "IP"로 지정하는 것 또한 중요한 부분입니다. 대상 유형을 인스턴스로 지정한다면 AWS Network Load Balancer 쉽게 이해하기 #1에서 언급한 것처럼 사용자의 요청이 NLB를 통과할 때 사용자의 출발지 IP가 그대로 보존된 상태로 전달됩니다. 그러나 대상 유형을 IP로 지정하게 된다면 사용자의 요청이 NLB를 통과할 때 출발지 IP가 NLB의 Private IP로 변경됩니다. ALB와 동일하게 작동하는 것이죠.

NLB 대상 그룹의 대상 유형

 

Network Load Balancer의 기타 기능

Connection Timeout

Connection Timeout(이하 유휴 제한 시간)은 사용자의 요청으로 생성된 사용자와 서버 간의 커넥션이 유지되는 시간을 뜻하는데요. Connection(이하 커넥션) 이 생성되고 난 후, 유휴 제한 시간에 도달하기 전까지 커넥션을 유지하고 사용자가 보낸 요청을 부하분산 대상으로 지정된 EC2에 지속적으로 전송합니다. NLB의 유휴 제한 시간은 TCP 350초, UDP 120초로 고정되며 이를 변경할 수 없습니다. TCP는 350초, UDP는 120초가 지날동안 커넥션이 사용되지 않는다면 NLB가 보유하고 있는 커넥션을 제거하게 되죠.

여담으로 TCP의 경우, 사용자 혹은 서버가 상대방에게 TCP Keepalive를 전송하면 이를 받은 NLB는 20초마다 사용와 서버에게 TCP Keepalive 패킷(데이터가 존재하지 않는)을 지속적으로 전송하여 커넥션을 유지하도록 합니다. TCP Keepalive는 커넥션을 지속적으로 유지할 목적으로 사용자 혹은 서버가 지속적으로 송신하는 패킷인데요. 유휴 제한 시간을 넘어 지속 사용하고자 할 때 사용됩니다. 그리고 더 이상 유지할 필요가 없다면 사용자 혹은 서버가 보내는 TCP Keepalive에 대해 더 이상 응답하지 않음으로써 커넥션을 종료하지요. 

Sticky

Sticky(이하 스티키)는 사용자가 한 번 접속한 적이 있는 서버를 기억해두고 커넥션이 사라진 상태에서 사용자가 다시 접속하더라도 기존 커넥션이 있었던 서버로 연결해 주는 기능입니다. 그리고 스티키를 활성화한 커넥션을 Sticky Session(이하 스티키 세션)이라고 부릅니다. ALB가 Cookie를 활용한 Stickiness를 지원하는 것처럼 NLB는 Source IP Address(이하 출발지 IP)를 활용하여 사용자가 한 번 접근한 적이 있는 서버로 요청을 지속적으로 전송하게 됩니다. 

NLB의 로드밸런싱 방식은 5-Tuple(Source IP Address, Source Port, Destination IP Address, Destination Port, Protocol)을 기반으로 한 Flow Hash Algorithm입니다. 

출처 : AWS Network Load Balancer 쉽게 이해하기 #1
[네트워크 엔지니어 환영의 기술블로그:티스토리]

위의 설명처럼 NLB는 5-Tuple 정보에 더해 TCP Sequnce Number까지 더한 6개의 정보를 가지고 부하분산을 실시합니다. 여기서 스티키 기능을 활성화하면 최초 요청 시 부하분산 방식에 따라 대상 그룹의 EC2를 선택하고 앞으로의 패킷은 출발지 IP가 동일하다면 줄곧 동일한 EC2로 요청을 전송합니다. 

스티키를 활용함에 있어서 한 가지 더 기억해야 할 것이 있으니 바로 Cross-zone load banalcing(이하 교차 영역 로드밸런싱)입니다. 교차 영역 로드밸런싱은 ELB(ALB, NLB, GWLB)가 갖는 기능으로 사용자로부터 들어온 요청을 Availability Zone(이하 AZ)를 가리지 않고 고르게 부하분산하는 기능을 의미하죠. 다시 말해 ELB가 보유한 DNS A 레코드에 대해 어느 AZ의 IP를 반환하든 모든 AZ의 EC2로 고르게 부하분산됨을 의미합니다. (참조 : AWS Elastic Load Balancer(ELB) 쉽게 이해하기 #2)

Cross-zone Load Balancing(참조 : AWS 설명서)

NLB의 스티키를 활성화시킴과 동시에 교차 영역 로드밸런싱을 비활성화한다면 어떻게 될까요? 앞서 NLB의 스티키 기능은 출발지 IP를 기준으로 삼아 IP가 동일하다면 동일한 EC2로 요청을 전송한다고 하였죠. 여기에 한 가지 기준이 더 추가됩니다. 바로 NLB의 IP(그림상 1.1.1.1 / 1.1.1.2)입니다. 교차 영역 로드밸런싱을 비활성화한다면 사용자가 접근하는 IP가 속한 AZ의 EC2에만 접근이 가능하며 접근 IP를 통해 다른 AZ의 EC2로 접근할 수 없습니다.

예를 들어 사용자가 NLB 접근을 위해 선택한 IP가 1.1.1.1이라면 AZ A의 EC2로만 부하분산이 될 것이며, 1.1.1.2로 접근하기 전까지는 AZ B의 EC2로 접근할 수 없죠. 이를 다시 말하면 사용가 1.1.1.1을 통해 통신하던 와중 1.1.1.2로 목적지를 변경하여 진입하게 된다면 아무리 스티키를 활성화한다 한들 원래 목적지(AZ A의 EC2)로 진입할 수 없다는 뜻입니다. 결국 스티키의 원래 의도와는 다르게 조건이 1가지(출발지 IP)가 아닌 2가지(출발지 IP, NLB IP)가 되는 것이며 예시와 같이 진입하는 목적지가 변경된다면 원래 통신을 유지하던 EC2로 가지 못 하는 불상사가 발생할 수 있습니다.

NLB의 스티키와 교차 영역 로드밸런싱 모두를 활성화한다면 어느 NLB IP로 접근한다 한들 동일한 EC2로 접근할 수 있습니다. 스티키의 원래 의도에 걸맞게 사용할 수 있게 되는 것이죠. 하여 NLB를 사용함과 동시에 스티키를 활성화하고자 한다면 교차 영역 로드밸런싱을 켜야 합니다. 실제 설정 상으로도 교차 영역 로드밸런싱을 활성화하지 않는다면 스티키 기능을 활성화할 수 없죠.

Proxy Protocol v2

대상 그룹 부분에서 언급한 것처럼 대상 유형을 IP로 지정하게 된다면 더 이상 NLB가 사용자의 출발지 IP를 보존하지 않습니다. 이에 대한 대안으로 Proxy Protocol V2(PP2)를 사용합니다. Proxy Protocol V2는 사용자의 출발지 IP 보존을 목적으로 탄생한 프로토콜입니다. 대표적인 출발지 IP 보존 프로토콜인 HTTP의 X-Forwarded-For Header가 있지만 TCP 레벨의 로드밸런서를 이를 이해할 수 없죠. 그렇기에 별도의 프로토콜을 두고 TCP 데이터에 추가적인 헤더(Proxy Protocol V2)를 집어넣어 사용자의 출발지 IP를 전달하는 것입니다. 아래서 언급할 Prviate Link 또한 NLB 사용 시 출발지 IP가 NLB의 IP로 변경되기 때문에 Proxy Protocol V2가 요긴하게 사용됩니다.

Private Link

AWS PrivateLink는 VPC와 AWS 서비스 간 프라이빗 연결을 제공하는 Amazon Virtual Private Cloud(Amazon VPC)의 기능입니다. PrivateLink를 사용하는 네트워크 트래픽은 퍼블릭 인터넷을 통해 이동하지 않으므로 외부 위협으로부터 안전합니다.

- 출처 : AWS 설명서 -

VPC EndpointVPC 내부 리소스가 AWS 글로벌 서비스, AWS 계정의 타 VPC에 안전하게 접근하기 위해 만든 서비스로 PrivateLink를 활용하여 사설 IP로 통신할 수 있는 경로를 마련하는 서비스입니다. 기본적으로 VPC 내부 리소스는 VPC 외부의 리소스와의 통신을 위해서는 공인 인터넷으로 나가야 하지만 그렇게 하지 않고 AWS 네트워크 내부에서 통신함으로써 혹시 모를 보안 위협을 막는 것입니다. 종류에는 Gateway Endpoint, Interface Endpoint와 함께 Gateway / Network Load Balancer Endpoint Service가 있습니다.

Privatelink를 활용해 타 서비스와 연결하는 VPC Endpoint(출처 : AWS 설명서)

위 그림에서 볼 수 있듯이 VPC 내부 리소스와 AWS의 다른 서비스 및 VPC와의 통신에서 공인 인터넷을 통하지 않고 나아가는 것을 볼 수 있죠. 그 중에서 VPC와 다른 VPC가 통신하기 위해서는 NLB를 사용하여야 합니다. 아래 그림에서 "Your account"의 인스턴스들이 "Third-party account"의 인스턴스에 접근하기 위해 Network Load Balancer를 활용한 Endpoint(PrivateLink)를 생성한 것을 볼 수 있습니다. Endpoint가 존재하기에 인스턴스 간 연결은 공인 인터넷을 통하지 않고도 가능해지죠. 아래 그림과 같이 말입니다.

Network Load Balancer를 활용한 VPC Endpoint(Privatelink)(출처 : AWS 설명서)

하지만 VPC Peering이나 Transit Gateway와 같이 VPC와 VPC를 연결할 수 있는 수단은 많죠. 그럼에도 불구하고 "왜 굳이 Endpoint와 함께 NLB를 사용하는가"에 대한 의문에 대한 답은 아래 구문에서 잘 설명하는 듯 합니다. NLB가 프록시 서버로서의 역할을 한다고 볼 수 있지요.

방화벽 규칙, 경로 정의, 라우팅 테이블, 인터넷 게이트웨이, VPC 피어링 연결 또는 관리형 CIDR 블록이 필요하지 않습니다. 이렇게 네트워크 아키텍처가 단순해지면 글로벌 네트워크를 더 쉽게 관리할 수 있습니다.

- 출처 : AWS 설명서 -

여기까지가 Netowrk Load Balancer에 대한 이야기입니다. Network Load Balancer 쉽게 이해하기 #1 이후로 거의 3년만에 2편을 제작하게 되었네요. AWS도 잊지 않고 계속 연재하도록 하겠습니다. 다음은 Gateway Load Balaner에 관한 글입니다. 감사합니다.

 

* 중요 참고 글
https://cloudguardians.medium.com/aws-nlb-stickiness-%ED%83%90%EA%B5%AC-580f6a0e6228 (AWS SA 신은수님 글)