쿠버네티스 LoadBalancer 서비스 활용 및 관리 가이드

LoadBalancer 타입의 서비스를 생성하고 외부 IP를 할당받는 것은 시작일 뿐입니다. 이 가이드는 “그다음은 무엇을 해야 하는가?”라는 질문에 답하며, LoadBalancer를 효과적으로 사용하고 관리하는 실용적인 방법에 초점을 맞춥니다.

1. 왜 LoadBalancer 관리가 중요한가?

LoadBalancer는 외부 사용자와 클러스터 내부의 동적인 Pod들을 연결하는 매우 중요한 다리입니다. 이 다리를 제대로 관리하지 않으면, 사용자는 서비스에 접속하지 못하거나, 업데이트 중에 서비스가 중단되거나, 특정 Pod에만 트래픽이 몰리는 현상을 겪을 수 있습니다.

따라서 단순히 트래픽을 분산시키는 것을 넘어, 안정적이고 예측 가능하게 서비스를 운영하는 방법을 알아야 합니다.


2. 핵심 관리 포인트 1: 안정적인 접속 주소 관리 (DNS)

kubectl get svc로 얻은 EXTERNAL-IP는 편리하지만, 서비스를 재생성하거나 클러스터 환경이 바뀌면 변경될 수 있는 유동적인 주소입니다. 사용자에게 이 IP 주소를 직접 제공하는 것은 매우 불안정한 방법입니다.

✔️ 해결책: DNS에 IP 주소 매핑하기

안정적인 서비스 제공을 위해, 할당받은 외부 IP를 고정된 DNS 이름에 연결해야 합니다.

  • 방법: 사용 중인 DNS 서비스(예: AWS Route 53, Cloudflare, 가비아 등)에서 A 레코드를 생성하여 도메인 이름을 외부 IP와 연결합니다.

  • 예시:

    • 도메인 이름: my-app.my-company.com
    • 연결할 IP 주소: 192.168.56.200 (MetalLB가 할당한 IP)
  • 장점:

    • 안정성: 나중에 서비스의 외부 IP가 192.168.56.201로 변경되더라도, 사용자는 DNS 이름으로만 접속하므로 영향을 받지 않습니다. 관리자는 DNS 레코드의 IP 주소만 업데이트하면 됩니다.
    • 가독성: IP 주소보다 훨씬 기억하고 사용하기 쉽습니다.

3. 핵심 관리 포인트 2: 트래픽 분산 모니터링

“요청이 정말 모든 Pod에 잘 분산되고 있는가?”를 확인하는 것은 서비스의 건강 상태를 파악하는 데 필수적입니다. 특정 Pod에만 트래픽이 몰리면 해당 Pod는 과부하로 다운될 수 있습니다.

✔️ 해결책 1: 수동으로 로그 확인하기 (테스트 환경)

우리가 실습에서 사용한 방법입니다. 각 Pod의 로그를 직접 확인하여 요청이 들어오는지 보는 가장 기본적인 방법입니다.

# 1. 트래픽을 받을 Pod 목록 확인
kubectl get pods -l app=nginx
 
# 2. 각 Pod의 최근 로그에서 접속 기록(GET /) 확인
kubectl logs <pod-name> --tail=10 | grep "GET /"

✔️ 해결책 2: 모니터링 시스템 구축 (운영 환경)

수십, 수백 개의 Pod 로그를 일일이 확인하는 것은 불가능합니다. 실제 운영 환경에서는 다음과 같은 모니터링 시스템을 사용해야 합니다.

  • 로그 수집/분석 (Centralized Logging):

    • 도구: EFK 스택 (Elasticsearch, Fluentd, Kibana) 또는 Loki
    • 방법: 모든 Pod의 로그를 중앙 서버로 전송하여 한곳에서 검색하고 분석합니다. “지난 10분간 5xx 에러가 발생한 Pod는?” 과 같은 복잡한 질의가 가능해집니다.
  • 메트릭 시각화 (Metrics & Visualization):

    • 도구: Prometheus (메트릭 수집) + Grafana (시각화)
    • 방법: 각 Pod의 초당 요청 수(RPS), 응답 시간, CPU/메모리 사용량과 같은 수치(메트릭)를 수집하여 그래프로 시각화합니다. 어떤 Pod에 부하가 몰리는지 직관적으로 파악할 수 있습니다.

4. 핵심 관리 포인트 3: 배포 및 스케일링 연계

LoadBalancer 서비스는 그 자체로 존재하지 않으며, 항상 뒤따르는 Deployment와 함께 동작합니다. 이 둘의 관계를 이해하면 무중단 운영이 가능해집니다.

  • 롤링 업데이트(Rolling Update) 시:

    • Deployment의 이미지를 새 버전으로 업데이트하면, 새 버전의 Pod가 하나씩 생성됩니다.
    • LoadBalancer는 새로 생성된 Pod가 “준비(Ready)” 상태가 되면 즉시 트래픽을 보내기 시작하고, 삭제되는 구버전 Pod로는 트래픽을 보내지 않습니다.
    • 이 모든 과정이 자동으로 일어나므로, 사용자는 서비스 중단을 전혀 느끼지 못합니다.
  • 스케일업/다운(Scale Up/Down) 시:

    • kubectl scale deployment --replicas=20 명령으로 Pod 수를 늘리면, LoadBalancer는 새로 생성된 Pod들을 자동으로 감지하여 트래픽 분산 대상에 포함시킵니다.
    • 반대로 Pod 수를 줄이면, 삭제된 Pod는 트래픽 분산 대상에서 자동으로 제외됩니다.

핵심: LoadBalancer는 안정적인 단일 진입점을 제공하고, 실제 워크로드의 변화(업데이트, 스케일링)는 Deployment가 처리하도록 역할을 분리하는 것이 쿠버네티스의 핵심적인 설계 사상입니다.


5. 핵심 관리 포인트 4: 세션 고정성 (Session Affinity)

기본적으로 LoadBalancer는 요청을 무작위 또는 라운드-로빈 방식으로 분산합니다. 하지만 특정 상황에서는 한 사용자의 모든 요청이 항상 동일한 Pod로 전달되어야 합니다. (예: Pod 내 메모리에 사용자 세션, 장바구니 정보 등을 저장하는 경우)

✔️ 해결책: sessionAffinity 설정하기

Service YAML 파일에 sessionAffinity 속성을 추가하여 이 동작을 제어할 수 있습니다.

  • 설정: sessionAffinity: ClientIP

    • 동일한 클라이언트 IP 주소에서 오는 모든 요청을 처음 처리했던 Pod로 계속해서 전달합니다.
  • YAML 예시:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      ports:
        - port: 80
      type: LoadBalancer
      sessionAffinity: ClientIP # 이 부분을 추가
      sessionAffinityConfig:
        clientIP:
          timeoutSeconds: 10800 # 고정 유지 시간 (초 단위)

결론

LoadBalancer 서비스를 생성하는 것은 외부 트래픽을 클러스터로 가져오는 첫걸음입니다. 진정한 가치는 이 서비스를 어떻게 관리하고 활용하는지에 달려 있습니다.

  • DNS 연결을 통해 사용자에게 안정적인 접속 포인트를 제공하고,
  • 모니터링 시스템으로 트래픽 분산 상태를 항상 주시하며,
  • Deployment와의 연계를 통해 무중단 업데이트와 탄력적인 스케일링을 구현하고,
  • 필요에 따라 세션 고정성을 설정하여 애플리케이션의 요구사항을 충족시키는 것

이것이 바로 쿠버네티스에서 LoadBalancer를 전문가처럼 다루는 방법입니다.