클라우드 컴퓨팅 & NoSQL/도커 & 쿠버네티스

쿠버네티스 Gateway의 이해

Terry Cho 2025. 12. 3. 06:31

아래 글은 Service에 대한 라우팅 메커니즘은 Ingress와 Gateway에 대한 설명이다.

아래 글은 Gemini 3.0 Pro를 이용하여 생성되었다. 

 

쿠버네티스 네트워크의 진화: Ingress에서 Gateway API까지

쿠버네티스 환경에서 마이크로서비스 아키텍처를 운영하다 보면 필연적으로 네트워크 라우팅 문제에 직면하게 된다. 클러스터 내부에는 수많은 Service가 존재하지만 이들 모두에게 외부 접속용 공인 IP(LoadBalancer 타입)를 할당하는 것은 비용 측면에서나 관리 측면에서나 매우 비효율적이다. 결국 단일 진입점을 통해 들어온 트래픽을 URL 경로나 호스트 이름을 기반으로 적절한 내부 서비스로 분배해 줄 L7 로드밸런서가 필요하게 되며, 이것이 바로 쿠버네티스 Ingress가 탄생하게 된 배경이다.

Ingress: 간결하지만 강력한 첫 번째 표준

Ingress는 클러스터 외부의 HTTP 및 HTTPS 요청을 내부의 Service로 라우팅하는 규칙들의 집합이다. Ingress 자체는 API 명세일 뿐이며 실제 트래픽 처리는 Nginx나 AWS ALB와 같은 Ingress Controller가 담당한다. Ingress의 가장 큰 특징은 하나의 리소스 안에 라우팅 규칙을 모두 정의하는 간결함이다.

앞서 본 개념도와 같이 /app1 경로로 들어오는 트래픽은 Service A로, /app2 경로로 들어오는 트래픽은 Service B로 보내는 상황을 가정해 보자. Ingress 설정 YAML은 아래와 같이 작성된다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-ingress
spec:
  rules:
  - http:
      paths:
      - path: /app1
        pathType: Prefix
        backend:
          service:
            name: service-a
            port:
              number: 80
      - path: /app2
        pathType: Prefix
        backend:
          service:
            name: service-b
            port:
              number: 80

위의 예제에서 볼 수 있듯이 Ingress 리소스 하나에 모든 경로 규칙과 백엔드 서비스 정보가 포함된다. 이는 설정이 직관적이고 간단한 웹 애플리케이션을 배포할 때 매우 유용하다. 하지만 서비스가 복잡해질수록 이러한 단순함은 오히려 독이 되기도 했다.

왜 Gateway API가 필요한가?

Ingress는 훌륭한 역할을 수행해 왔지만 명확한 한계점이 존재했다. 첫째는 벤더 종속성 문제이다. Ingress 스펙은 매우 단순하기 때문에, 리다이렉션이나 헤더 조작 같은 고급 기능을 사용하려면 각 Ingress Controller 구현체마다 다른 annotations를 사용해야 했다. 이는 설정의 이식성을 떨어뜨리는 주원인이 되었다. 둘째는 역할 분리의 어려움이다. 클러스터 인프라를 관리하는 운영자와 애플리케이션을 개발하는 개발자가 동일한 Ingress 리소스를 수정해야 했기에 권한 관리나 실수로 인한 장애 발생 가능성이 높았다. 이러한 확장성 부족과 운영상의 불편함을 해결하고, 더 풍부한 라우팅 기능을 표준화된 방식으로 제공하기 위해 등장한 것이 바로 Gateway API이다.

Gateway API: 역할 중심의 차세대 표준

Gateway API는 리소스를 역할별로 분리하여 설계되었다. 인프라 운영자는 Gateway 리소스를 통해 로드밸런서의 진입점을 정의하고, 애플리케이션 개발자는 HTTPRoute 리소스를 통해 자신의 서비스로 향하는 트래픽 규칙만을 정의한다.

개념도에 나온 예제처럼 /new-app은 Service C로, /legacy-app은 Service D로 라우팅하는 상황을 Gateway API로 구현해 보자. 설정은 크게 Gateway 정의와 Route 정의로 나뉜다.

먼저 인프라 운영자가 설정하는 Gateway YAML이다. 여기서는 80 포트를 리스닝하는 진입점만을 정의한다.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: standard
  listeners:
  - name: http
    protocol: HTTP
    port: 80

다음은 개발자가 설정하는 HTTPRoute YAML이다. 앞서 생성된 my-gateway에 연결되며 실제 라우팅 규칙을 담고 있다. (Gateway와 HTTPRoute의 연결은 parentRefs를 이용하여, HTTPRoute에서 해당룰이 적용되는 Gateway를 지정한다.)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
spec:
  parentRefs:
  - name: my-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /new-app
    backendRefs:
    - name: service-c
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /legacy-app
    backendRefs:
    - name: service-d
      port: 80

이처럼 Gateway API를 사용하면 인프라 설정과 라우팅 설정이 완벽하게 분리된다. 개발자는 운영자의 Gateway 설정 전체를 건드릴 필요 없이 자신의 HTTPRoute만 관리하면 되므로 더욱 안전하고 유연한 운영이 가능하다. 또한 헤더 매칭, 트래픽 가중치 분할 등 고급 기능이 표준 스펙에 포함되어 있어 벤더 종속성 없이 일관된 기능을 사용할 수 있다는 것이 큰 장점이다.

마무리

Ingress가 간단한 단일 리소스로 L7 라우팅의 기초를 닦았다면, Gateway API는 이를 역할 기반으로 세분화하고 확장성을 더한 완성형 모델이다. 단순한 구조가 필요하다면 Ingress도 여전히 유효하지만, 멀티 테넌시 환경이나 복잡한 트래픽 관리가 필요한 현대적인 쿠버네티스 환경에서는 Gateway API가 확실한 대안이 될 것이다.