[Infra] Kubernetes 기초 : 네트워크 - Ingress

고수가 되고 싶은 감자·2026년 9월 28일
post-thumbnail

쿠버네티스의 기본 네트워크 리소스인 Service를 배우고 나니

"외부 접속이 필요하면 그냥 Service를 type: LoadBalancer로 설정해서 띄우면 끝 아닌가?"

이런 생각이 들었다.

컨테이너가 몇 개 없는 단일 프로젝트라면 그 말대로 LoadBalancer 타입의 서비스 하나만 띄워도 아무런 문제가 없다.
하지만 서비스 규모가 커져 사용자(user), 상품(item), 주문(order), 결제(pay) 등 마이크로서비스 파드가 20개로 늘어나는 순간, Service 단독 구성은 곧바로 두 가지 치명적인 한계에 부딪힌다.

  1. 로드밸런서 비용 폭탄: 20개의 서비스를 외부에 노출하기 위해 각각 type: LoadBalancer를 선언하면, AWS에 L4 로드밸런서인 NLB가 20개 생성된다. 로드밸런서 기본 유지비만으로도 매달 막대한 클라우드 비용이 청구된다.
  2. 도메인 및 URL 경로(L7) 분기 불가: Service는 오직 IP와 포트 번호(L4)만 볼 줄 안다. 따라서 하나의 도메인(api.shop.com)으로 들어온 요청을 /orders는 주문 파드로, /pay는 결제 파드로 나누어 보내는 HTTP URL 경로 기반 라우팅을 처리할 수 없다.

결국 우리는 "바깥에는 로드밸런서를 딱 1개만 세워 비용을 아끼고, 도메인과 URL 경로를 분석해 내부의 20개 서비스(ClusterIP)로 길을 나눠주는 똑똑한 L7 안내데스크"가 필요하다.

이 한계를 해결하기 위해 등장한 것이 바로 Ingress이며, 여기서부터 Ingress-Nginx, Gateway API, 그리고 Istio로 이어지는 쿠버네티스 네트워킹의 확장이 시작된다.


1. Ingress를 구현하는 2가지 대표 방식 : AWS ALB vs Ingress-Nginx

쿠버네티스의 YAML 파일은 그저 '종이 주문서'일 뿐이다.
kind: Ingress라는 주문서를 작성했을 때, 이를 실제로 구현하는 방식은 현업에서 크게 2가지 아키텍처로 나뉜다. 여기서 ALB만 쓰는 구조와 NLB + Ingress-Nginx를 함께 쓰는 구조의 차이가 발생한다.

[방식 A : AWS ALB 단독 사용]
외부 유저 ──▶ [AWS ALB (L7, 여기서 경로 분기 끝)] ──▶ [Service (ClusterIP)] ──▶ [Pod]

[방식 B : AWS NLB + Ingress-Nginx 조합]
외부 유저 ──▶ [AWS NLB (L4, 단순 통과)] ──▶ [Ingress-Nginx 파드 (L7, 클러스터 안에서 경로 분기)] ──▶ [Service (ClusterIP)] ──▶ [Pod]

방식 A. AWS Load Balancer Controller (AWS ALB 방식)

클러스터 외부의 AWS ALB에게 안내데스크(L7 경로 분기) 역할을 통째로 맡기는 방식이다.

  • Ingress YAML을 배포하면 AWS에 ALB가 딱 1개 생성된다. (이 구조에서는 NLB를 아예 쓰지 않는다.)
  • 장점: AWS WAF(웹 방화벽), ACM(무료 SSL 인증서)과 즉시 연동되며, 클러스터 내부의 CPU/메모리를 소모하지 않는다. 또한 target-type: ip 설정을 통해 노드를 거치지 않고 파드 IP로 직결 라우팅할 수 있다.
  • 단점: AWS에 강하게 종속되며, 복잡한 라우팅 룰이나 세밀한 속도 제한(Rate Limit) 설정에는 제약이 있다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop-alb-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip          # 파드 IP로 직결
    alb.ingress.kubernetes.io/group.name: shared-alb   # 여러 Ingress를 단 1개의 ALB로 통합
spec:
  ingressClassName: alb
  rules:
    - host: api.shop.com
      http:
        paths:
          - path: /orders
            pathType: Prefix
            backend:
              service:
                name: order-svc    # 뒤쪽의 ClusterIP 서비스와 연결
                port:
                  number: 80

방식 B. Ingress-Nginx Controller (NLB + 내부 Nginx 파드 방식)

AWS의 ALB를 쓰지 않고, 쿠버네티스 클러스터 내부에 직접 Nginx 웹서버 파드(Ingress-Nginx)를 띄워서 안내데스크 역할을 시키는 방식이다.

  • 클러스터 안에 있는 Ingress-Nginx 파드를 외부와 연결해 줘야 하므로, 그 앞단에 단순 문지기 역할인 AWS NLB(type: LoadBalancer)를 딱 1개만 세운다.
  • 트래픽 흐름: 외부 유저가 NLB(L4)를 통과해 클러스터 안의 Ingress-Nginx 파드(L7)에 도착하면, 이 Nginx 파드가 Ingress YAML 규칙을 읽고 /orders는 order-svc로, /pay는 pay-svc로 토스해 준다.
  • 장점: AWS가 아닌 온프레미스나 GCP 등 어디서나 100% 똑같이 동작하며, Nginx가 가진 강력한 기능(세밀한 리다이렉트, 헤더 조작, 접속 제한)을 마음껏 쓸 수 있다.

2. Ingress의 한계와 차세대 표준 : Gateway API

Ingress 덕분에 로드밸런서 비용도 아끼고 경로 분기도 해결했다. 그런데 서비스 규모가 커지면서 Ingress 자체에 두 가지 심각한 구조적 한계가 드러났다.

  1. 어노테이션 지옥 (Annotation Hell):
    기본 Ingress 문법에는 SSL 설정, 타임아웃, 카나리 배포 같은 기능이 아예 없다. 그래서 위 YAML처럼 annotations: 밑에 AWS 전용 주석이나 Nginx 전용 주석을 20~30줄씩 덕지덕지 붙여야만 했다.
  2. 단일 파일 권한 충돌 (인프라팀 vs 개발팀):
    로드밸런서의 보안과 인증서를 관리하는 인프라 엔지니어와, /orders 같은 API 경로를 추가하는 백엔드 개발자가 똑같은 Ingress YAML 파일 하나를 같이 수정해야 한다. 개발자가 경로를 고치다가 실수로 SSL 인증서 설정을 지워버리면 전체 서비스 장애가 발생한다.

이 문제를 근본적으로 해결하기 위해 쿠버네티스가 새롭게 내놓은 공식 차세대 표준이 바로 Gateway API다.

[인프라 엔지니어 담당] ──▶ Gateway (로드밸런서 생성, 443 포트 개방, TLS 인증서 장착)
                                 │
                                 │ (연결)
                                 ▼
[백엔드 개발자 담당]   ──▶ HTTPRoute ("/orders" 경로 매핑, 90:10 카나리 배포 설정)

1) 인프라 엔지니어는 Gateway만 관리한다

인프라 팀은 로드밸런서의 물리적 설정과 보안만 정의해 두고 권한(RBAC)을 잠근다.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-gateway
  namespace: infra-system
spec:
  gatewayClassName: aws-alb-class
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: shop-tls-cert

2) 백엔드 개발자는 HTTPRoute만 관리한다

개발자는 인프라 설정(Gateway)을 건드릴 필요 없이, 본인의 네임스페이스에서 경로와 카나리 배포(가중치 분할)만 안전하게 선언한다. 어노테이션 없이 표준 문법(weight)만으로 트래픽을 90:10으로 쪼갤 수 있다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: order-route
  namespace: order-team
spec:
  parentRefs:
    - name: prod-gateway
      namespace: infra-system
  hostnames:
    - "api.shop.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /orders
      backendRefs:
        - name: order-svc-v1
          port: 80
          weight: 90     # 기존 버전에 90% 트래픽 할당
        - name: order-svc-v2
          port: 80
          weight: 10     # 신규 버전에 10% 트래픽 할당 (Canary 배포)

3. 마지막 퍼즐 : 그럼 Istio(Service Mesh)는 왜 쓰는 걸까?

지금까지 다룬 Ingress, Ingress-Nginx, Gateway API는 모두 한 가지 공통점이 있다.
바로 "클러스터 바깥에서 안으로 들어오는 입구 트래픽(North-South Traffic)"만 관리한다는 점이다.

그런데 현업에서 마이크로서비스(MSA)가 50개, 100개로 늘어나면 진짜 문제는 입구를 통과한 그 이후, 즉 클러스터 내부에서 파드들끼리 서로 통신할 때(East-West Traffic) 터진다.

  • 주문 파드 -> 결제 파드 -> 포인트 파드 -> 알림 파드로 연쇄 호출이 일어날 때, 만약 포인트 파드 하나가 느려지면 앞단의 모든 파드가 줄줄이 멈춰버리는 연쇄 장애가 발생한다.
  • 또한 금융/결제 서비스에서는 클러스터 내부의 파드끼리 통신할 때도 해킹을 막기 위해 전 구간 암호화(mTLS)가 필수적인데, 기본 Service(ClusterIP)에는 그런 기능이 없다.

이 "클러스터 내부 파드 간의 통신 제어와 보안"을 해결하기 위해 등장한 기술이 바로 Istio (서비스 메시, Service Mesh)다.

[일반 구조]
[주문 컨테이너] ────────────────(맨몸 통신)────────────────▶ [결제 컨테이너]

[Istio 적용 구조 (사이드카 패턴)]
[주문 파드: 주문 컨테이너 + Envoy 프록시] ──(mTLS 암호화 / 서킷 브레이커)──▶ [결제 파드: Envoy 프록시 + 결제 컨테이너]

Istio의 핵심 동작 원리 : 사이드카(Sidecar) 프록시

  • Istio를 도입하면, 모든 비즈니스 파드가 뜰 때마다 그 파드 안에 Envoy라는 초소형 네트워크 대리인(사이드카 컨테이너)이 1개씩 자동으로 함께 장착된다.
  • 이제 애플리케이션 컨테이너들은 직접 통신하지 않고, 무조건 옆자리에 탄 Envoy 대리인을 통해서만 대화를 주고받는다.
  • Istio가 해주는 일:
    1. 입구 관문 (Istio IngressGateway): 외부 트래픽을 받아들이는 고성능 관문 역할(Ingress 대체)을 수행한다.
    2. 자동 암호화 (mTLS): 개발자가 코드를 한 줄도 안 고쳐도, 파드와 파드 사이의 모든 내부 통신을 자동으로 암호화한다.
    3. 장애 전파 차단 (Circuit Breaker & Retry): 특정 파드가 응답이 없으면 자동으로 재시도(Retry)하거나, 아예 회로를 차단(Circuit Breaking)해 전체 시스템이 죽는 것을 막는다.
    4. 완벽한 가시성 (Observability): 어떤 파드가 어떤 파드를 호출할 때 몇 ms가 걸렸고 어디서 에러가 나는지 모든 통신 지도를 실시간으로 그려준다. (참고로 최근 쿠버네티스 생태계에서는 Istio 또한 설정 문법으로 앞서 배운 표준 Gateway API를 그대로 채택해 통합되고 있다.)

4. 마치며 : 한눈에 보는 선택 기준

쿠버네티스 네트워크 기술들의 관계와 선택 기준을 한 표로 정리하면 다음과 같다.

기술 명칭담당하는 구간핵심 역할 및 선택해야 하는 순간
Service (ClusterIP)클러스터 내부 기본 연결모든 구조의 필수 부품. 변하는 파드들을 묶어 고정 IP와 도메인(CoreDNS)을 부여할 때
Ingress (AWS ALB)외부 -> 내부 입구 (L7)AWS 환경에서 가장 간편하게 단일 ALB로 도메인/경로 분기와 WAF/SSL을 연동하고 싶을 때
Ingress-Nginx (NLB + Nginx)외부 -> 내부 입구 (L7)클라우드 종속성을 피하고, 앞단에 NLB 1개만 둔 채 내부 Nginx 파드로 세밀한 L7 제어를 하고 싶을 때
Gateway API외부 -> 내부 입구 (차세대 표준)기존 Ingress의 어노테이션 남발을 없애고, 인프라팀(Gateway)과 개발팀(HTTPRoute)의 권한을 분리 및 카나리 배포를 표준화할 때
Istio (Service Mesh)입구 + 내부 파드 간 통신 전체입구 라우팅을 넘어, 내부 파드끼리의 mTLS 보안 암호화, 서킷 브레이커(장애 격리), 세밀한 트래픽 제어까지 필요한 대규모 MSA 환경일 때

결국 이 기술들은 서로 동떨어진 것이 아니라, "단일 진입점 확보(Service) -> 입구 L7 라우팅 통합(Ingress / Ingress-Nginx) -> 역할 분리 및 표준화(Gateway API) -> 내부 동서 트래픽 제어(Istio)"라는 명확한 한계 극복을 위해 단계별로 발전해 온 하나의 흐름이다.

이상.

profile
DevOps 엔지니어 지망생

0개의 댓글