Load Balancer / Health Check / Traffic Routing

3줄 요약

  • Load Balancer는 트래픽을 나누는 장비가 아니라 target 선택, health 판단, connection 유지, 배포 전환을 책임지는 운영 경계다.
  • Health check 200은 “프로세스가 응답했다”에 가까울 수 있으므로 liveness, readiness, 핵심 기능 smoke test를 구분해야 한다.
  • 배포 품질은 readiness false, target draining, graceful shutdown, idle timeout, sticky/session 전략이 맞물릴 때 안정된다.

핵심 정리

  • LB는 listener, rule, target group, routing algorithm, health check, idle timeout, access log로 동작한다.
  • Routing은 round robin, least connections, weighted/canary, host/path/header rule, stickiness 같은 정책을 포함한다.
  • Readiness는 새 트래픽을 받아도 되는지의 신호이고, liveness는 프로세스를 재시작해야 하는지의 신호다.
  • Draining은 target을 새 요청에서 제외하되 기존 연결과 진행 중 요청이 끝날 시간을 주는 절차다.
  • WebSocket, SSE, long polling, gRPC는 idle timeout, keepalive, connection draining, target rebalance에 민감하다.

헷갈리는 지점

  • LB가 있으면 장애 target은 자동으로 완벽히 숨겨진다고 생각하기 쉽다.
    • 핵심 판단 포인트는 모든 target이 unhealthy거나 health check가 실제 장애를 못 보면 LB도 잘못된 target으로 보낼 수 있다는 것이다.
  • readiness에 모든 dependency를 넣으면 안전하다고 생각하기 쉽다.
    • 핵심 판단 포인트는 공통 dependency 장애 때 모든 target이 unready가 되어 전체 트래픽이 끊길 수 있다는 것이다.
  • 배포 실패를 앱 코드 문제로만 보기 쉽다.
    • 핵심 판단 포인트는 readiness 전환, LB deregistration delay, app shutdown timeout, connection close 순서가 배포 성공률을 결정한다는 것이다.
  • sticky session은 세션 문제를 간단히 해결한다고 생각하기 쉽다.
    • 핵심 판단 포인트는 특정 target 과부하, 배포 중 세션 끊김, scale-in 시 사용자 영향이 생길 수 있다는 것이다.

확인 질문

  • Health check는 정상인데 실제 API가 실패하는 이유는 무엇인가?
    • health path가 실제 API와 다른 route, dependency, Host, protocol, auth, DB migration 상태를 사용하기 때문이다.
  • readiness와 liveness를 나누는 이유는 무엇인가?
    • 살아 있는 프로세스와 트래픽을 받을 준비가 된 프로세스를 다르게 다루기 위해서다.
  • draining이 배포에서 필요한 이유는 무엇인가?
    • 새 요청은 막으면서 기존 요청과 장기 연결이 갑자기 끊기지 않게 시간을 주기 위해서다.
  • cloud LB 5xx를 볼 때 앱 로그와 함께 무엇을 봐야 하는가?
    • LB access log의 target status, target health reason, listener/rule, security group, subnet/NACL, idle timeout, 최근 배포를 함께 봐야 한다.