[Kubernetes] 내 트래픽은 어떻게 Pod까지 도달할까 (feat. AWS Load Balancer Controller)

도니·2026년 1월 26일

1. 프롤로그 : "Ingress만 만들면 끝인 줄 알았다"

"EKS 환경에서 Route 53부터 Pod까지 통신이 어떻게 이루어지나요?" 라는 질문을 받았을 때, 깊게 생각한 적이 없어서 대답을 하지 못했다. 평소에 무의식적으로 Ingress yaml 파일만 배포하면 알아서 된다고 생각했지, 그 뒤단에서 AWS Load Balancer Controller가 무슨 일을 하는지, 패킷이 실제로 어디를 거쳐 가는지 명확히 설명하지 못했다. 오늘은 그 '보이지 않는 길'을 시각화해본다.

2. 전체적인 큰 그림 (The Big Picture)

사용자가 브라우저에 api.my-service.com을 입력 했을 때, 내 EKS Pod에 도달하기까지는 크게 4단계를 거친다.

  1. Route 53 (DNS): "이 도메인이 어디로 가야해?" -> ALB의 주소 (DNS Name)를 알려줌.
  2. AWS ALB (L7): "어떤 규칙(Path/Host)이지?" -> 규칙에 맞는 Target Group을 찾음.
  3. Target Group: "누구한테 보낼까?" -> 등록된 타겟 (Pod IP 혹은 Node IP)으로 토스.
  4. Pod: 요청 및 수신 처리.

여기서 핵심은 3번과 4번 사이, 즉 ALB가 EKS 내부의 Pod를 어떻게 찾느냐 이다.

3. 핵심 플레이어: AWS Load Balancer Controller

Kubernetes 자체는 AWS ALB를 직접 제어할 능력이 없다. 이 둘을 이어주는 통역사가 바로 AWS Load Balancer Controller다.

  • 내가 k8s에 Ingress 리소스를 생성하면?
  • -> 컨트롤러가 이를 감지하고 AWS에 ALB를 프로비저닝한다.
  • -> 그리고 Ingress 규칙에 맞춰 Traget Group을 생성하고 타겟을 등록한다.

4. 통신 모드의 차이: Instnace Mode vs IP Mode (중요!)

해당 사항에서 제일 중요한 포인트는 "ALB가 트래픽을 어디로 꽂아주는가?" 이다. 여기에 두 가지 모드가 있다.

① Instance Mode (NodePort 방식 - 레거시/기본)

  • 흐름: ALB -> Worker Node (NodePort) -> iptables -> pod
  • ALB는 Pod가 어디있는지 모른다. 그냥 EC2(Node) 아무 곳이나 보낸다.
  • Node에 도착한 트래픽은 kube-proxy가 설정한 iptables 규칙을 타고, 진짜 Pod가 있는 다른 Node로 점프(Hop)해야 할 수도 있다.
  • 단점: 불필요한 네트워크 홉(Hop) 발생, 지연 시간(Latency) 증가, SNAT로 인한 Source IP 보존 복잡성.

② IP Mode (AWS VPC CNI 방식 - 권장)

  • 흐름: ALB -> Pod IP (Direct)
  • AWS EKS는 VPC CNI를 사용하기 때문에 Pod가 VPC 대역의 리얼 IP를 가진다.
  • ALB가 Target Group에 Pod의 IP를 직접 등록해서 트래픽을 다이렉트로 꽂아준다.
  • 장점: 경로가 단순해서 빠르다 (Latency 감소). 불필요한 Node간 이동이 없다.
  • 설정: Ingress Annotation에 alb.ingress.kubernetes.io/target-type: ip라고 명시해야한다.

5. 결론 "수박 껍질"을 깨고 안을 보자

그동안 나는 target-type: ip 한 줄을 복사-붙여넣기 하면서도 이게 왜 좋은지 몰랐다.

  • Instance Mode는 "일단 현과문(Node)로 던져, 안에서 알아서 찾아가겠지" 방식이고,
  • IP Mode는 "방 번호(Pod IP)알아? 그럼 바로 방으로 들어가" 방식이다.

✅추가로 생각해 볼 수 있는 질문

Pod IP가 바뀔 때 Target Group은 어떻게 될까?

  • 계속 변동된다.
    - AWS Load Balancer Controller가 계속 수정함.

[작동 메커니즘]

  1. Pod 생성: 새로운 Pod가 뜨고 IP(예: 10.0.1.5)를 할당받는다.
  2. K8s 감지: Kubernetes는 이 Pod가 Running 및 Ready 상태가 되면 EndpointSlice라는 리소스에 이 IP를 추가합니다.
  3. Controller 동작: AWS Load Balancer Controller는 K8s의 EndpointSlice를 계속 감시(Watch) 한다. 신규 IP가 생겼을 때 바로 감지
  4. AWS API 호출: 컨트롤러가 AWS API(RegisterTargets)를 호출하여 해당 Target Group에 10.0.1.5를 등록합니다.
  5. Health Check: ALB는 등록된 IP로 Health Check를 보내고, 성공하면 트래픽을 보내기 시작합니다.

Pod가 삭제 될 때도 마찬가지 매커니즘으로 동작을 하는데, Poㅇ가 사라지면 컨트롤러가 AWS API를 호출해 Target Group에서 IP를 제거하는 방식이다.
이 때 과정에서 약간의 딜레이가 발생한다. 그래서 Pod가 먼저 죽어버리면 그 찰나의 순간에 들어온 요청은 500에러가 난다. 그렇기 때문에 Graceful Shutdown(preStop + sleep)을 설정해야한다.

profile
세상만사에 호기심

0개의 댓글