L4 스위치의 A to Z (Load Balancing, Traffic Flow, SSL Offload 등)
서버 부하 분산은 부하 분산 Network Switch 혹은 Nginx등의 소프트웨어가 담당합니다. 즉, 외부로부터의 요청을 받으면 이를 서버로 적절히 나누어 주게 됩니다.
개발을 하며 소프트웨어로 로드밸런싱을 구축하는 경험은 해보았으니, 하드웨어인 L4 스위치를 통해 어떻게 로드밸런싱을 하는지를 다뤄보겠습니다.
L4 스위치의 역할과 Nginx의 역할은 거의 유사하기 때문에, L4 스위치의 기능들을 모두 이해한다면 Nginx같은 웹 서버에 대해서 이해하기 편합니다.
L4 스위치란?
L4 스위치를 사용하면 외부에서 들어오는 모든 요청을 서버가 아닌 L4 스위치가 받아서 서버들에게 적절히 나누어 줍니다.
위 그림의 Load Balancing을 하는 부분이 바로 L4 스위치의 역할입니다.
마치 리버스 프록시와 유사한 모습이죠.
L4 스위치는 다음과 같은 일들을 합니다.
- 부하 분산
- TCP,UDP,HTTP와 같은 프로토콜들의 헤더를 분석하여 그 정보를 바탕으로 부하 분산
- Source IP 혹은 Destination IP를 NAT(Network Address Translation) 하여 전송.
클라이언트와 서버가 3-way handshake
를 거쳐 논리적 연결이 생성됨을 나타내는 Connection
을 생성하면 중간자 역할인 L4 스위치 역시 Connection을 생성하고 리스트를 관리합니다.
또한 이 과정에서 3-way handshake 역시 L4 스위치를 통해 실시됩니다.
L4스위치의 Connection은 Connection time out 값을 가지는데, 이는 일정 시간 사용되지 않은 Connection을 삭제하고 클라이언트와 서버 측에 필요 시 Connection을 새로 맺도록 Reset Flag가 담긴 Packet을 전송할 수 있도록 합니다.
L4 스위치의 구성 요소
L4 스위치는 공인 IP와 함께 포트번호가 붙습니다.
IP 뿐만 아니라 Port가 있어야, 해당 서버에서 제공하는 웹 서비스를 어느 Port에서 접근하는지를 알 수 있습니다.
L4 스위치의 이름도, Layer 4의 정보인 Port를 사용하기 때문에 L4 스위치인 것입니다. 👀
구성 요소 더 자세히 보기
L4 Switch의 플로우는 다음과 같습니다.
먼저 L4 Switch는 외부 사용자들이 접속 시 사용하는 IP와 Port를 가진 Virtual Server
를 여러 대 가질 수 있습니다.
또한 특정 Virtual Server에 도달한 요청을 서버들의 집합에 전달하는데, 이 집합을 Pool이라고 합니다.
Pool은 다수의 Pool Member로 이루어져있고 각각의 Pool Member는 IP와 Port를 고유하게 가지고 있기 때문에 엄연히 다른 Pool Member로서 구성됩니다.
그리고 Pool로 전달된 요청은 로드밸런싱 정책에 따라 Pool Member에게 전달하게 됩니다.
L4 스위치의 장점
이제 위 내용을 바탕으로 알아본 L4 스위치의 장점은 다음과 같습니다.
- 로드밸런싱을 통해 서버의 부담을 고르게 분산합니다.
- 공인 IP가 각각의 서버에 필요하지 않고, L4 스위치 1개에만 필요하게 됩니다.
- 외부에서는 서버의 IP를 알 수 없습니다.
L4 로드밸런싱과 L7 로드밸런싱
L4 스위치는 Layer4를 이용하여 로드밸런싱을 하는 것 뿐만 아니라 Layer7까지 제어하며 로드밸런싱을 실시할 수 있습니다.
즉, L4 Type Virtual Server
와 L7 Type Virtual Server
로 나뉘게 됩니다.
그리고 L7 로드밸런싱은 Layer4와 Layer7을 모두 수반하는 기능을 뜻합니다.
L4 스위치와 3-way handshake
TCP/IP 에 대해 공부했다면 3-way handshake를 한 번 쯤 들어보게 됩니다.
바로 TCP를 사용하는 송신자와 수신자간의 신뢰성을 위한 과정인데요, 만약 사용자와 서버 사이에 L4 스위치가 존재한다면 L4 스위치가 중간에서 3-way handshake에 필요한 패킷(SYN, SYN/ACK, ACK) 을 대신 전달해주거나, 자신이 송/수신자가 되어 패킷을 주고 받습니다.
대략적인 이미지는 위와 같지만, 모든 경우에서 L4 스위치가 위의 역할을 하진 않는다고 합니다.
그리고 L4 스위치는 Virtual Server Type
이 4인지 7인지에 따라 다르게 행동합니다.
L4 Virtual Server
의 트래픽 플로우
L4 로드밸런싱을 담당하는 L4 Virtual Server
는 Performance L4 Type이라고 불리며, 트래픽 중개 및 제어보다는 전달(Forwading)에 초점이 맞춰져 있습니다. 그렇기에 Layer 4 프로토콜인 TCP/UDP를 제어하면서 사용자가 전달한 요청을 그대로 Pool Member(실제 서버)에 전달합니다.
위 그림을 보면 3-way handshaking에서 L4 스위치의 역할은 단순히 로드밸런싱을 실시하며 패킷을 전달하는 일을 수행합니다.
따라서 부하가 상대적으로 덜하며, 성능이 극대화되기 때문에 Layer 7에 대한 간섭을 원하지 않는다면 좋은 선택이 될 수 있습니다.
L7 Virtual Server
의 트래픽 플로우
L7 로드밸런싱을 담당하는 L7 Virtual Server
는 Standart Type이라 불리며, Layer 4의 TCP/UDP 뿐만 아니라 Layer 7의 HTTP,SMTP,DNS 등의 프로토콜 헤더를 제어하거나 필요한 정보를 삽입할 수 있습니다.
L4 스위치가 프로토콜 헤더에 직접 개입하기 때문에 서버와 클라이언트간의 3-way handshaking
이 아닌
Client ↔ L4 스위치
L4 스위치 ↔ Server
의 형태로 3-way handshaking
이 이루어지게 됩니다.
따라서 L4 스위치는 이때 전달보다는 중개자의 역할을 하게 되고, 이를 Proxy라고 부릅니다.
그리고 L4 스위치는 HTTP 헤더를 제어할 수 있다고 하였는데, 활용 사례는 다음과 같습니다.
만약 인터넷 브라우저(Chrome, firefox 등) 에 따라 제공되는 웹페이지를 다르게 하고 싶다면,
HTTP 헤더에 있는 User-agent Header를 보고 브라우저 종류를 확인 후, 각각 다른 웹 페이지로 Forwarding 하는 방식으로 L4 스위치를 활용할 수 있습니다.
위 사례 처럼 L7 Virtual Server
를 사용한다면 다양한 방식의 로드밸런싱과 포워딩이 가능해집니다.
L4 스위치의 SSL Offload
Nginx에도 있는 기능인 SSL Offload입니다.
SSL Offload란? 웹 서비스를 제공하는 서버가 SSL을 암호화 / 복호화 하는 과정을 L4 스위치가 대신 함으로써 서버는 평문 데이터로 통신을 하게된다. 따라서 서버의 부하를 줄이고, L4 스위치에만 인증서를 등록하면 되므로 취약점이 발생해도 관리가 편하고 시간과 비용이 절약된다.
먼저 L4 스위치가 없는 인프라의 모습입니다.
각 서버가 SSL 인증서를 가지고 있고, 클라이언트는 각 서버와 통신할 때마다 SSL HandShake를 거칩니다. 그리고 각 서버는 SSL 암/복호화를 수행하기 때문에 이에 대한 부담이 주어집니다.
L4 스위치로 SSL Offload를 구현한 모습입니다.
각 서버의 SSL 인증서가 L4 스위치로 이동했고, 클라이언트와 L4 스위치가 SSL HandShake를 실시합니다. 이후 클라이언트로부터 암호화(443)된 요청을 받은 L4 스위치의 Virtual Server는 이 요청을 복호하 하고 서버에게 평문 데이터(80)로 전송합니다.
따라서 서버는 443포트를 사용하는 대신 80포트를 사용합니다.
이처럼 L4 스위치의 포트를 거쳐 목적지 포트가 서버의 포트로 변경되는 것(위 예시에서는 443→80)을 Port Translation이라고 합니다.
L4 스위치의 Health Check
지난번 무중단 배포를 구현할 때 멈춰있는 인스턴스를 구동하기 전에 API 요청을 보낸 것처럼, 서버의 상태를 확인하는 것을 Health Check
라고 합니다.
Virtual Server로 사용자에게서 요청을 받을 경우, 헬스 체크를 통해 기능 상태가 확인된 서버에게만 로드밸런싱을 실시합니다.
헬스 체크 설정에는 Interval과 Time Out이라는 두가지 요소가 들어갑니다.
Time Out
: 헬스 체크를 반복적으로 시도하는 정해진 시간 한도
Interval
: 타임 아웃 전까지 헬스 체크를 시도하는 간격
L4 스위치는 헬스 체크를 위해 대표적으로 TCP와 HTTP를 사용합니다.
먼저 TCP를 사용하여 헬스 체크를 실시하는 예시입니다.
L4 스위치는 서버와 3-way HandShake를 실시하고, 정상적으로 패킷을 주고받으면 서버의 상태가 정상이라 판단합니다.
그러나 커넥션 생성이 목적이 아니므로 3-way HandShake 이후 바로 Fin 패킷을 날려 커넥션을 제거합니다.
다음으로 HTTP를 사용하여 헬스 체크를 하는 예시입니다.
TCP와 마찬가지로 3-way HandShake를 실시하지만, 추가로 HTTP Request를 전송하여 Default 웹 페이지를 요구합니다. 이 때 추가로 Response String을 설정하여 특정 조건의 웹 페이지를 요구할 수도 있습니다.
L4 스위치의 Connection(커넥션)
커넥션은 L4 스위치를 통해 사용자와 서버가 맺는 논리적인 연결입니다. TCP 통신을 할 때 커넥션을 생성하기 위해 3-way HandShake를 하게 되는데, L4 스위치가 존재한다면 L4 스위치 또한 커넥션을 생성하게 됩니다.
따라서 다음 그림처럼 사용자와 L4 스위치, 서버가 각각 커넥션을 가지게 됩니다.
L4 스위치는 로드 밸런싱을 하면서 커넥션도 관리하는 장비입니다. 사용되지 않는 커넥션을 제거하여 서버의 부하를 줄여주기도 합니다. 따라서 커넥션에 대해 타임 아웃이 존재하며 커넥션이 제거 되면 사용자는 다시 L4 스위치를 통해 3-way Handshake를 실시합니다.
Persistence(Sticky)
Persistence는 사용자가 한 번 접속하여 커넥션을 맺었던 서버를 기억하는 또 다른 커넥션입니다.
사용자가 서비스 사용을 위해 서버에 접속하면 커넥션이 생성됨과 동시에 Sticky Session을 생성합니다.
사용자가 더 이상 통신을 하지 않아 커넥션 타임 아웃이 지나 커넥션이 사라져도 L4 스위치는 스티키 세션을 유지하여 사용자가 접속했던 서버를 기억합니다. 그리고 재접속시 과거 이력이 있던 서버로 로드 밸런싱하여 커넥션을 맺도록 합니다.
만약 스티키 세션이 없다면 서버1을 통해 요청을 처리하던 중 자리를 비워 커넥션이 제거되면, 다음 커넥션시 어느 서버로 커넥션이 생성될 지 모르고 서버1에서 처리하던 작업을 이어서 처리하는 것이 불가능해집니다.
reference