93. LoadBalancer - 클라우드 연동 K8s 서비스

⚠️ 이 문서는 쿠버네티스(Kubernetes) 서비스 타입 중, 내부망 전용인 ClusterIP나 못생긴 30000번대 포트를 쓰는 NodePort의 한계를 넘어, AWS나 GCP 같은 퍼블릭 클라우드 인프라와 직접 대화하여 진짜 무거운 물리/가상 로드밸런서(예: AWS ALB/NLB) 장비를 클러스터 바깥에 자동으로 찍어내어, 전 세계 고객에게 예쁜 외부 공인 IP와 80/443 포트를 열어주는 상용 서비스 배포의 끝판왕 'LoadBalancer' 타입을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 쿠버네티스의 네트워킹 리소스(Service) 중 하나로, 자체적으로 트래픽을 처리하는 기능에 더해 외부 클라우드 벤더(Cloud Provider)의 API를 찔러 외부의 로드밸런서 기계를 생성하고 K8s 노드들과 배관을 연결하는(Provisioning) 자동화 트리거다.
  2. 가치: 개발자가 AWS 웹 콘솔에 들어가서 마우스로 타겟 그룹을 잡고 로드밸런서를 생성하고 라우팅 규칙을 짜는 끔찍한 수작업 인프라 세팅(Ops)을 완전히 소멸시켰다. yaml 파일 하나만 던지면 1분 만에 완벽한 L4 부하 분산기가 탄생한다.
  3. 기술 체계: 내부 구조적으로는 매트료시카 인형과 같다. 외부 LB 인프라 $\rightarrow$ 쿠버네티스 NodePort $\rightarrow$ 쿠버네티스 ClusterIP $\rightarrow$ 실제 Pod IP 라는 4단계의 깊숙한 깔때기 흐름으로 트래픽을 꽂아 넣는다.

Ⅰ. NodePort의 초라함과 찐 로드밸런서의 등장

고객에게 구멍 난 포트를 줄 수는 없다. 번듯한 대문을 세워야 한다.

  1. 상용 서비스의 관문 한계:
    • 앞서 배운 NodePort는 모든 서버의 31000번 같은 이상한 포트를 열어주는 기술이다. http://서버IP:31000 로 고객이 들어와야 하는데, 어떤 고객이 네이버를 저런 못생긴 주소로 접속하겠는가? 무조건 80(HTTP)이나 443(HTTPS) 포트를 제공해야 한다.
    • 또, 1번 서버가 죽으면 고객이 2번 서버 IP를 치고 들어와야 하는 로드밸런싱의 부재라는 치명적 단점이 있었다.
  2. 마법의 YAML 한 줄 (type: LoadBalancer):
    • 쿠버네티스 Service yaml 파일에 type: LoadBalancer라고 딱 한 줄을 고치고 kubectl apply를 친다.
    • 쿠버네티스의 '클라우드 컨트롤러 매니저(CCM)'가 이 명령을 낚아채어, AWS의 API로 "야! 외부 공인 IP 달린 네트워크 로드밸런서(NLB) 하나 빨리 만들어!"라고 주문을 넣는다.
  3. 클라우드 인프라의 자동 셋업:
    • 1분 뒤, 진짜 AWS 인프라 단에 NLB 기계가 한 대 뚝딱 생성되고, 이 NLB는 K8s 클러스터의 모든 워커 노드들의 30000번대 포트(NodePort)를 자기 뒤통수(타겟 그룹)에 거미줄처럼 다 연결해 둔다.
    • 이제 고객은 NLB의 예쁜 IP(203.x.x.x:80)로 들어오면 트래픽이 노드들을 거쳐 목적지 파드로 부드럽게 쏟아진다.

📢 섹션 요약 비유: NodePort가 우리 아파트(클러스터) 1동, 2동 담벼락에 개구멍(31000번 포트)을 뚫어놓고 손님 보고 기어 들어오라는 짓이라면, LoadBalancer는 아파트 단지 정문 바깥 큰길가에 엄청나게 화려한 유리로 된 '통합 고객 접견실(AWS NLB)' 건물을 지어버리는 것입니다. 손님이 정문으로 우아하게 걸어오면 접견실 직원이 알아서 1동, 2동의 개구멍으로 짐을 밀어 넣어주는(라우팅) 완벽한 VIP 의전 시스템입니다.


Ⅱ. 4중 매트료시카 라우팅 구조의 이해

편리함 이면에는 꽤 복잡한 네트워킹 홉(Hop)이 숨어있다.

  1. 데이터 패킷의 눈물 나는 여정:
    • 이 서비스 타입은 독자적인 기술이 아니다. 아래 계층을 모두 감싸 안는 합체 로봇이다.
    • ① 스마트폰 고객 $\rightarrow$ ② 외부 [AWS LoadBalancer] 도달 (포트 80) $\rightarrow$ ③ K8s의 [NodePort] 진입 (포트 31000) $\rightarrow$ ④ 내부망 [ClusterIP] 가상 주소 변환 (10.96.x.x) $\rightarrow$ ⑤ kube-proxy의 룰을 타고 진짜 [Pod IP] (10.1.1.5)에 도착하여 마침내 Nginx 화면을 본다.
  2. 트래픽의 불필요한 핑퐁 (External Traffic Policy):
    • 위의 3번 단계에서 AWS 로드밸런서가 트래픽을 아무 노드나(예: 노드 A) 골라서 던진다.
    • 그런데 하필 노드 A에는 목적지 파드가 없다. 그럼 노드 A는 이 트래픽을 파드가 있는 노드 B로 다시 던져준다(SNAT 핑퐁 발생). 불필요한 네트워크 지연이 생긴다.
  3. Local 정책의 최적화:
    • 이를 막기 위해 externalTrafficPolicy: Local 옵션을 주면, 로드밸런서가 파드가 없는 노드 A에게는 아예 트래픽을 쏘지 않고, 파드가 떠 있는 노드 B에게만 직접 트래픽을 꽂아주어 응답 속도(Latency)를 극단적으로 줄이고 클라이언트의 진짜 IP 보존도 가능해진다.

📢 섹션 요약 비유: 택배 기사(로드밸런서)가 아파트 단지에 와서 아무 동(노드 A) 경비실에나 물건을 던지면, 1동 경비 아저씨가 "어 이거 2동 물건인데?" 하며 다시 2동으로 걸어가서 전해줘야 하는 짜증 나는 핑퐁 딜레이가 생깁니다. 'Local 정책'은 택배 기사에게 "무조건 물건 받을 사람이 사는 동(파드가 있는 노드)의 경비실로만 직배송해라!"라고 똑똑한 내비게이션을 쥐여주는 최적화 스킬입니다.


Ⅲ. LoadBalancer의 한계와 Ingress로의 진화

돈 낭비의 끝판왕. 서버(서비스)가 늘어날수록 회사는 파산한다.

  1. 1 서비스 = 1 로드밸런서의 저주:
    • 마이크로서비스 아키텍처(MSA)에서는 주문, 결제, 장바구니, 리뷰 등 외부에 노출해야 할 API 서비스가 50개가 넘어간다.
    • 이 50개 서비스에 전부 type: LoadBalancer를 매겨버리면?
    • AWS에 한 달에 수만 원씩 하는 비싼 로드밸런서 기계가 진짜 물리적으로 50대가 붕어빵처럼 생성된다. 트래픽은 쥐꼬리만 한데 한 달에 로드밸런서 유지 비용으로만 수백만 원이 증발하는 돈 잔치가 열린다.
  2. L4 장비의 무식함 (URL 라우팅 불가):
    • 게다가 이 LoadBalancer는 바보 같은 L4(네트워크 계층) 장비 기반이다.
    • /order로 들어오면 주문 파드로, /pay로 들어오면 결제 파드로 트래픽을 예쁘게 분기(L7 라우팅)해 주는 고차원적인 지능이 아예 없다. (그냥 IP와 포트만 보고 쏴준다.)
  3. Ingress (인그레스)의 등판 예고:
    • "이거 돈 아까워서 안 되겠다. AWS 로드밸런서 기계는 클러스터 앞단에 딱 1대만(월 3만 원) 사서 띄워놓고, 그 1대로 들어온 트래픽을 쿠버네티스 내부의 똑똑한 가상 라우터(L7)가 넘겨받아 URL 주소별로 50개 서비스에 착착 나눠주게 만들자!"
    • 이렇게 무식한 비용 낭비를 해결하고 똑똑한 L7 URL 라우팅을 수행하기 위해 탄생한 쿠버네티스의 궁극적 리소스가 바로 다음에 배울 **인그레스(Ingress)**다.

📢 섹션 요약 비유: 50개의 입점 상가(서비스)가 있는 쇼핑몰을 지었는데, 상가마다 자기들 전용 에스컬레이터와 입구(AWS 로드밸런서)를 밖으로 따로따로 50개를 뚫어달라고 요구해서 건축비가 거덜 나는 꼴입니다. 이를 뜯어고쳐, 거대한 정문(1대의 로드밸런서)은 딱 1개만 만들고 그 정문 안에 아주 똑똑한 엘리베이터 안내양(인그레스)을 한 명 둬서 손님이 가고 싶은 매장(URL) 층수를 누르면 알아서 다 올려보내 주어 비용을 1/50로 아끼는 구조로 넘어가게 됩니다.