본문 바로가기
DevOps

AWS ALB Ingress Controller – 포트 & Path 기반 라우팅 완전 정리

by Rainbound-IT 2025. 8. 8.
반응형

목차

     

     

    쿠버네티스 환경에서 AWS ALB Ingress Controller를 사용하면, 하나의 ALB로 여러 서비스에 트래픽을 라우팅할 수 있습니다.
    이 글에서는 포트와 Path를 활용한 라우팅 개념부터 Terraform 예제, 그리고 포트 매핑 케이스별 매트릭스와 패킷 흐름까지 전부 정리합니다.


    1. ALB + Kubernetes에서 포트 흐름 이해하기

    ALB → Kubernetes Service → Pod 컨테이너 포트는 아래 4단계로 연결됩니다.

    [Client]
       ↓ Listener Port
    [ALB Listener]
       ↓ Target Group Port (Service Port)
    [Kubernetes Service]
       ↓ targetPort
    [Pod Container Port]

     

    구분 설명 예시
    ALB Listener Port ALB가 외부 요청을 받는 포트 80, 443, 81 등
    Ingress backend.service.port.number ALB Target Group이 연결하는 Service Port 80
    Service Port 쿠버네티스 내부에서 Service가 노출하는 포트 80
    targetPort Pod 컨테이너 내부에서 앱이 리스닝하는 실제 포트 3000
     

    💡 중요 포인트

    • Listener 포트와 Service Port는 반드시 같을 필요 없습니다.
    • Service Port → targetPort 변환은 K8s Service에서 처리됩니다.

    2. ALB 포트 매핑 케이스별 매트릭스


     

    케이스 ALB Listener Port Service Port (backend.service.port.number) targetPort (Pod Port) 특징 / 동작 방식 주의사항
    ① 동일 포트 매핑 80 80 80 모든 구간 포트 동일. 관리 단순. 컨테이너가 해당 포트 리스닝 필요.
    ② Listener ≠ Service 81 80 80 ALB가 81번에서 받은 요청을 Service 80번에 전달. 헷갈리지 않게 문서화 필수.
    ③ Service ≠ targetPort 80 80 3000 Service가 80으로 받고 Pod의 3000으로 전달. 앱 내부 포트와 외부 노출 포트를 분리 가능.
    ④ Listener ≠ Service ≠ targetPort 81 80 3000 각 단계별 포트 변환. 트러블슈팅 시 흐름 추적 필요.
    ⑤ 여러 Listener → 각기 다른 Service 80, 81 80, 81 3000, 4000 포트별로 서비스 분리. Listener/Service 매핑 설계 중요.
    ⑥ 같은 Listener, Path별 다른 Service 80 80, 80 3000, 4000 경로 기반 라우팅. 비용 절감에 유리. Path 충돌 방지 필요.
     

    3. 패킷 흐름 다이어그램

    아래는 /app1과 /app2가 같은 ALB(80포트)에서 다른 서비스로 라우팅되는 예입니다.

    클라이언트
       ↓ http://ALB:80/app1
    [ALB Listener :80]
       ↓ (Rule: /app1)
    [Target Group : service-a:80]
       ↓
    [Service-a Port:80 → targetPort:3000]
       ↓
    [Pod 컨테이너 :3000]
    
    클라이언트
       ↓ http://ALB:80/app2
    [ALB Listener :80]
       ↓ (Rule: /app2)
    [Target Group : service-b:80]
       ↓
    [Service-b Port:80 → targetPort:4000]
       ↓
    [Pod 컨테이너 :4000]
     

    4. Service Port 중복 가능 여부

    • 가능: 같은 네임스페이스 내 서로 다른 Service에서 동일한 port 값 사용 가능
    • 불가: 같은 Service 내 spec.ports.port 중복
    • NodePort 타입: nodePort 값은 클러스터 전체에서 고유해야 함

    5. 같은 ALB 그룹, 같은 포트, Path별 다른 서비스 라우팅 예제

    아래 예제는

    • ALB 하나 (group.name 동일)
    • Listener: 80 포트
    • /app1 → service-a:80
    • /app2 → service-b:80
      로 라우팅합니다.

    Service 예시

    # service-a
    apiVersion: v1
    kind: Service
    metadata:
      name: service-a
      namespace: app
    spec:
      selector:
        app: app-a
      ports:
        - port: 80
          targetPort: 3000
    
    # service-b
    apiVersion: v1
    kind: Service
    metadata:
      name: service-b
      namespace: app
    spec:
      selector:
        app: app-b
      ports:
        - port: 80
          targetPort: 4000

    Terraform – Ingress 2개로 Path 분리

    # Ingress for /app1
    resource "kubernetes_ingress_v1" "alb_ingress_app1" {
      metadata {
        name      = "alb-ingress-app1"
        namespace = "app"
        annotations = {
          "kubernetes.io/ingress.class"           = "alb"
          "alb.ingress.kubernetes.io/scheme"      = "internet-facing"
          "alb.ingress.kubernetes.io/target-type" = "ip"
          "alb.ingress.kubernetes.io/group.name"  = "shared-alb"
          "alb.ingress.kubernetes.io/listen-ports" = jsonencode([{ HTTP = 80 }])
        }
      }
      spec {
        rule {
          http {
            path {
              path      = "/app1"
              path_type = "Prefix"
              backend {
                service {
                  name = "service-a"
                  port { number = 80 }
                }
              }
            }
          }
        }
      }
    }
    
    # Ingress for /app2
    resource "kubernetes_ingress_v1" "alb_ingress_app2" {
      metadata {
        name      = "alb-ingress-app2"
        namespace = "app"
        annotations = {
          "kubernetes.io/ingress.class"           = "alb"
          "alb.ingress.kubernetes.io/scheme"      = "internet-facing"
          "alb.ingress.kubernetes.io/target-type" = "ip"
          "alb.ingress.kubernetes.io/group.name"  = "shared-alb"
          "alb.ingress.kubernetes.io/listen-ports" = jsonencode([{ HTTP = 80 }])
        }
      }
      spec {
        rule {
          http {
            path {
              path      = "/app2"
              path_type = "Prefix"
              backend {
                service {
                  name = "service-b"
                  port { number = 80 }
                }
              }
            }
          }
        }
      }
    }

    6. 동작 흐름

    http://<ALB-DNS>/app1  → service-a:80 → Pod:3000
    http://<ALB-DNS>/app2  → service-b:80 → Pod:4000
    • ALB Listener: 80 포트
    • Path별로 다른 Target Group(Service)로 라우팅
    • Service Port는 동일(80)해도 서비스 이름으로 구분되므로 충돌 없음

    7. 운영 시 주의사항

    1. Path는 고유해야 함 → 중복 시 Controller가 충돌로 인식
    2. 경로 우선순위는 ALB에서 자동 부여
    3. Host 조건을 추가하면 같은 Path도 구분 가능 (app1.example.com vs app2.example.com)
    4. target-type=ip 모드 사용 시, ALB가 직접 Pod IP:targetPort로 연결 → NodePort 불필요

    🔚 마무리

    AWS ALB Ingress Controller를 쓰면 하나의 ALB로 여러 서비스를 깔끔하게 운영할 수 있습니다.
    포트와 Path 구조를 이해하면, 비용을 절감하면서도 라우팅을 자유롭게 구성할 수 있습니다.
    Terraform으로 관리하면 선언형으로 재현이 가능하니, 실무 환경에서는 반드시 IaC로 적용하는 걸 추천드립니다.

    반응형

    댓글