본문 바로가기 메뉴 바로가기


kakao의 L3DSR 구성 사례

Overview

서비스 웹서버 Load Balancing을 위한 메커니즘으로 KAKAO에서는 L3DSR 방식을 사용하고 있습니다. 멀티IDC에서 L3DSR 방식을 활용, IDC 위치나 서버의 물리적인 위치에 따른 제한없이 서비스 웹서버 Load Balancing이 가능하도록 구성하고 있습니다.

L3DSR 소개

보통 서비스에서는 Inbound traffic 대비 Outbound traffic이 월등히 높은데 Outbound traffic을 SLB에서 모두 수용하게 될 경우 리소스 소모가 커질 수 밖에 없습니다. 그래서 Outbound traffic을 서버가 SLB에 전달하지 않고 직접 클라이언트에게 전달해 SLB의 리소스 소모 방지를 위해 사용하는 구성이 DSR(Direct Server Return) 구성입니다. 그리고 클라이언트의 Request를 서버로 전달함에 있어 어떤 헤더를 이용하는지에 따라 L2/L3 DSR로 구분하게 됩니다. L3DSR 은 Load Balancing 을 위한 메커니즘 중 DSR 방식에서 기존 L2 Layer 의 DSR 방식의 한계를 개선하기 위해 사용하는 기술입니다. L3DSR 구성은 IP 헤더중 어떠한것을 이용하는지에 따라 IP Tunnel 기반과 TOS(DSCP) 기반으로 구분되는데 카카오는 DSCP 기반의 L3DSR 방식을 사용하고 있습니다.

L2DSR 과 L3DSR의 차이

L2DSR은 L2 Layer 헤더인 MAC 주소 변경을 통해 클라이언트의 Request가 전달되는 반면 L3DSR은 IP헤더를 변조하여 서버에 Request를 전달하는 구성입니다. L2DSR의 경우는 MAC 주소 변경을 위해 서버와 ADC 모두 동일한 Broadcast 도메인에 포함되어야 했고, 그로인한 물리적 회선, 위치등의 한계성이 있었습니다. 그러나 L3DSR의 경우 SLB에서 IP 주소 변경을 통해 클라이언트의 Request가 서버로 전달되기 때문에 L2DSR에서의 물리적인 한계성을 극복 할 수 있습니다. 카카오는 서로 다른곳에 각각 위치한 IDC라도 L3DSR 구성을 통해 Load Balancing이 가능하도록 사용하고 있습니다.

L3DSR 구성에서의 패킷 흐름

위 그림을 보면 클라이언트는 Destination IP가 211.115.115.100 인 서버로 Request를 보낸것이므로 동일한 IP로부터 Response를 받아야 합니다. LB장비에서는 211.115.115.100 에 바인딩된 Real Server호스트들의 IP정보를 갖고 있고 IP헤더의 Destination IP를 변조 후 실제 서버로 전달합니다. L2DSR의 경우는 L2 Layer의 Destination MAC 주소를 변조 후 서버로 전달하는데 이 부분이 L2DSR과 L3DSR의 차이점입니다. 이때 서버에서는 Destination IP가 211.115.115.100 으로 들어온 패킷을 자신의 IP가 아니라고 판단하고 버리게 되므로 서버의 lo:0 인터페이스에 VIP를 설정하여 사용합니다.

cat /etc/sysconfig/network-scripts/ifcfg-lo:0
#DSR Loopback
DEVICE=lo:0
IPADDR=211.115.115.100
NETMASK=255.255.255.255
NETWORK=211.115.115.100
BROADCAST=211.115.115.100
ONBOOT=yes
NAME=loopback:0
  • Netmask 를 255.255.255.255로 설정하여 Broadcast를 방지.
  • 그리고 카카오에서는 DSCP 기반의 L3DSR 방식을 사용하고 있는데 이는 LB 장비에 설정된 DSCP 값과 서버의 DSCP 값을 동일하게 맞추어 서버에서 Loopback Interface까지 전달이 되도록 IPTABLE로 설정합니다.
cat /etc/sysconfig/iptables
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0] -A PREROUTING -m dscp --dscp 10 -j DADDR --set-daddr=211.115.115.100 COMMIT
  • DSCP 값은 LB장비와 동일하게 통일. (위 예제는 “10”)
  • 서버에서는 위 IPTABLE에 따라 IP 헤더의 TOS필드의 DSCP bit값이 동일할경우 211.115.115.100 으로 오는 요청을 허용.

위와 같은 설정으로 211.115.115.100 의 주소로 들어온 패킷도 서버에서는 버리지 않고 Loopback Interface에 할당된 IP로 응답하게 됩니다. 이때 서버에서는 LB장비를 거칠필요 없이 Direct로 클라이언트로 응답을 하게 되는것이 L3DSR 방식입니다.

DSR 구성의 부하 분산 방식

DSR 구성의 부하 분산 방식
  1. Round Robin
    • 모든 서버에 균일한 횟수로 접속.
    • 서버의 부하 상태 등에 대한 고려 없이 일률적으로 부하를 분산함으로써 효과적인 부하 분산을 기대하기 어려움.
  2. Least connection
    • 서버들 중 세션수가 가장 적은 서버로 사용자 접속을 유도하는 방식.
    • 서버의 부하 상태등을 고려하여 분삼함.
    • 단점 : 서버 1대를 추가로 투입할 경우 현재 세션수가 0인 신규 투입 서버로 Request가 몰리는 현상도 있음.

카카오에서는 Least connection 의 단점을 회피하고자 Round Robin 방식을 사용중입니다.

HealthCheck (Real Server HealthCheck)

  1. L2 헬스 체크: ARP 응답 확인 (디폴트로 ICMP 주기의 10배로 자동 설정)
  2. L3 헬스 체크: Ping 응답 확인
  3. L4 헬스 체크: 서버에 TCP/UDP 서비스 포트가 활성화되어 있는지 확인
  4. L7 헬스 체크: 어플리케이션이 올바르게 동작하는지 확인

HTTP 예: L2/L3 헬스 체크 성공 => L4 헬스 체크 성공 => 리얼서버 업 => L7 헬스 체크 성공 => 리얼서버 업 유지

L4 Health Check

Layer 4 계층의 TCP/UDP 서비스 port를 체크하는 방식.

TCP 서비스 경우 LB 장비에서는 바인딩된 서버의 포트로 TCP SYN 을 전송하여 SYN+ACK 응답이 오는지를 확인하며 응답이 없다면 서버의 서비스 상태에 문제가 있다고 인식을 하고 바인딩을 하지 않습니다. 그리고 기본적으로 서버가 SYN+ACK을 응답할 경우 서버의 Socket 낭비를 막기 위해 바로 RST을 통해 세션을 끊습니다. 이방법은 LB장비의 부하가 적고 서버의 Socket 낭비가 없는 이점이 있는 반면 실제 서비스 어플리케이션단은 체크를 할수 없는 문제점이 있습니다.

L4 헬스 체크

L7 Health Check

Layer7 계층의 어플리케이션 응답을 체크하는 방식.

기본적으로 서버와 TCP 세션을 맺고 Request를 (ex. GET /health_check.html) 통해 응답 코드 확인하는 방식입니다. 주기적으로 서버와 세션을 맺기 때문에 부하가 발생하지만 어플리케이션 상태까지 체크할 수 있기 때문에 L4 Health Check 보다 확실한 헬스체크가 가능합니다.

L7 헬스 체크

카카오 웹서버군은 거의 대부분 L7 Health Check 방식을 사용합니다. 그로인해 보다 확실한 서비스 안정성을 유지할 수 있도록 합니다.

LB 장비의 설정 예 (L7 HealthCheck)

SLB 설정
server port 80
session-sync
tcp
tcp keepalive 10 1
server port 443
session-sync
tcp
tcp keepalive 10 1
server remote-name Hostname 10.10.10.1
port default disable
port http
port http url "GET /health_check.html"
port ssl
port ssl url "GET /health_check.html"
server virtual store-app1 211.115.115.100
tos-marking 10 hc-l3-dsr ====> means "DSCP=10"
port http
bind http Hostname http Hostname http
bind ssl Hostname ssl Hostname ssl
헬스 체크 tcpdump 예

Conclusion

L2DSR 구성은 이미 여러곳에서 사용되어 오고 있습니다. L3DSR구성도 이미 많이 소개가 되고 보편화 되어 여러사이트에서 사용중인것으로 알고 있습니다. 그러나 L2DSR의 한계점을 극복하기 위해, L3DSR 구성이 서비스의 확장과 멀티 IDC에서의 운영, 확장, 안정성에서도 더 나은 구성임이 분명하기에 조금이나마 도움이 되었으면 하는 바램으로 글을 작성하게 되었습니다.

terry.k
terry.k

위로