Kubernetes Gateway와 Ingress API 비교

Navendu Pottekkat

Navendu Pottekkat

October 21, 2022

Ecosystem

몇 달 전, 새로운 Kubernetes Gateway API가 베타로 승격되었습니다.

안정적인 Kubernetes Ingress API수십 가지 구현체가 있는데, 왜 외부 트래픽을 처리하기 위해 또 다른 API가 필요할까요? 새로운 Gateway API가 Ingress API의 어떤 문제를 해결할까요? 이는 Ingress API의 종말을 의미할까요?

이 글에서는 이러한 질문에 답하기 위해 이러한 API를 직접 사용해보고 어떻게 발전했는지 살펴보겠습니다.

서비스에 대한 외부 접근 표준화: Ingress API

Kubernetes Ingress API는 Kubernetes 서비스를 외부 트래픽에 노출시키기 위해 표준화되었습니다. Ingress API는 라우팅 및 SSL 종료와 같은 기능을 도입하여 기본 서비스 유형인 NodePortLoadBalancer의 한계를 극복했습니다.

Kubernetes Ingress

20개 이상의 Ingress 컨트롤러 구현체가 있습니다. 이 글에서는 Apache APISIX와 그 Ingress 컨트롤러를 예제로 사용하겠습니다.

APISIX Ingress 컨트롤러

APISIX 또는 다른 Ingress 구현체를 구성하기 위해 Ingress 리소스를 생성할 수 있습니다.

아래 예제는 APISIX Ingress를 사용하여 애플리케이션의 두 버전 간에 트래픽을 라우팅하는 방법을 보여줍니다:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
spec:
  ingressClassName: apisix
  rules:
    - host: local.navendu.me
      http:
        paths:
          - backend:
              service:
                name: bare-minimum-api-v1
                port:
                  number: 8080
            path: /v1
            pathType: Prefix
          - backend:
              service:
                name: bare-minimum-api-v2
                port:
                  number: 8081
            path: /v2
            pathType: Prefix

: Kubernetes에서 Apache APISIX Ingress 컨트롤러를 사용하여 Ingress를 설정하는 방법에 대해 더 알아보려면 이 실습 튜토리얼을 확인하세요.

Ingress API는 특정 컨트롤러 구현에 종속되지 않기 때문에 APISIX를 다른 Ingress 컨트롤러로 교체해도 비슷하게 작동합니다.

이것은 간단한 라우팅에는 적합합니다. 하지만 API가 제한적이며, Ingress 컨트롤러가 제공하는 모든 기능을 사용하려면 어노테이션에 의존해야 합니다.

예를 들어, Kubernetes Ingress API는 리라이트를 구성하기 위한 스키마를 제공하지 않습니다. 리라이트는 업스트림/백엔드 URL이 Ingress 규칙에 구성된 경로와 다를 때 유용합니다.

APISIX는 이 기능을 지원하며, 이를 활용하려면 사용자 정의 어노테이션을 사용해야 합니다:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
  annotations:
    k8s.apisix.apache.org/rewrite-target-regex: "/app/(.*)"
    k8s.apisix.apache.org/rewrite-target-regex-template: "/$1"
spec:
  ingressClassName: apisix
  rules:
    - host: local.navendu.me
      http:
        paths:
          - backend:
              service:
                name: bare-minimum-api
                port:
                  number: 8080
            path: /app
            pathType: Prefix

이렇게 하면 /app 접두사가 있는 요청을 백엔드로 라우팅하고 접두사를 제거하도록 APISIX를 구성하는 Ingress 리소스가 생성됩니다. 예를 들어, /app/version 요청은 /version으로 전달됩니다.

어노테이션은 선택한 Ingress 컨트롤러에 따라 다릅니다. 이러한 "독점적" 확장은 Ingress API의 초기 이식성 범위를 제한했습니다.

사용자 정의 CRD > Ingress API

어노테이션에 의존하는 것은 Ingress 컨트롤러의 사용성을 희생하는 것입니다.

따라서 컨트롤러는 Ingress API의 한계를 극복하기 위해 자체 사용자 정의 리소스를 생성했습니다. 아래 예제는 APISIX의 사용자 정의 리소스를 사용하여 애플리케이션의 두 버전 간에 트래픽을 라우팅하도록 Ingress를 구성하는 방법을 보여줍니다:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: api-routes
spec:
  http:
    - name: route-1
      match:
        hosts:
          - local.navendu.me
        paths:
          - /v1
      backends:
        - serviceName: bare-minimum-api-v1
          servicePort: 8080
    - name: route-2
      match:
        hosts:
          - local.navendu.me
        paths:
          - /v2
      backends:
        - serviceName: bare-minimum-api-v2
          servicePort: 8081

이러한 CRD는 Ingress를 구성하기 훨씬 쉽게 만들었지만, 특정 Ingress 컨트롤러 구현에 종속됩니다. Ingress API가 발전하지 않으면 사용성과 이식성 사이에서 선택해야 했습니다.

Ingress 확장 및 Gateway API로의 진화

Ingress API가 고장난 것은 아니었고, 단지 제한적이었습니다. Gateway API는 이러한 한계를 극복하기 위해 설계되었습니다.

(Gateway API)는 표현적이고 확장 가능하며 역할 지향적인 인터페이스를 통해 Kubernetes 서비스 네트워킹을 발전시키는 것을 목표로 합니다 ...

이는 앞서 언급한 다양한 Ingress 컨트롤러의 사용자 정의 CRD에서 영감을 받았습니다.

Gateway API는 Ingress API의 기능 "위에" 많은 기능을 추가합니다. 이에는 HTTP 헤더 기반 매칭, 가중치 기반 트래픽 분할 및 Ingress API에서 사용자 정의 독점 어노테이션이 필요한 다른 기능들이 포함됩니다.

APISIX Ingress 리소스를 사용한 트래픽 분할 (ApisixRoute/v2 참조):

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: traffic-split
spec:
  http:
    - name: rule-1
      match:
        hosts:
          - local.navendu.me
        paths:
          - /get*
      backends:
        - serviceName: bare-minimum-api-v1
          servicePort: 8080
          weight: 90
        - serviceName: bare-minimum-api-v2
          servicePort: 8081
          weight: 10

Gateway API를 사용한 트래픽 분할 (Canary 트래픽 롤아웃):

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: traffic-split
spec:
  hostnames:
  - local.navendu.me
  rules:
  - backendRefs:
    - name: bare-minimum-api-v1
      port: 8080
      weight: 90
    - name: bare-minimum-api-v2
      port: 8081
      weight: 10

Ingress API의 또 다른 개선점은 Gateway API가 관심사 분리를 어떻게 처리하는지입니다. Ingress에서는 애플리케이션 개발자와 클러스터 운영자가 동일한 Ingress 객체에서 작업하며, 서로의 책임을 알지 못해 잘못된 구성이 발생할 가능성이 있습니다.

Gateway API는 구성을 Route와 Gateway 객체로 분리하여 애플리케이션 개발자와 클러스터 운영자에게 자율성을 제공합니다. 아래 다이어그램이 이를 명확히 설명합니다:

Gateway API의 관심사 분리

이제 Ingress API의 종말인가요?

Gateway API는 비교적 새롭고, 그 구현체들은 끊임없이 변화하고 있습니다. 반면, Ingress API는 안정적인 릴리스 상태이며 시간의 시험을 견뎌냈습니다.

만약 사용 사례가 단순한 라우팅만 포함하고, 추가 기능을 위해 사용자 정의 어노테이션을 사용하는 것에 문제가 없다면, Ingress API는 여전히 훌륭한 선택입니다.

Gateway API가 Ingress API의 상위 집합이기 때문에, 둘을 통합하는 것이 합리적일 수 있습니다. SIG Network 커뮤니티 덕분에 Gateway API는 여전히 성장 중이며 곧 프로덕션 준비가 될 것입니다.

대부분의 Ingress 컨트롤러와 서비스 메시는 이미 Ingress API와 함께 Gateway API를 구현했으며, 프로젝트가 발전함에 따라 더 많은 구현체가 등장할 것입니다.

개인적으로는 적어도 지금은 Ingress 또는 Gateway API 대신 Apache APISIX와 같은 Ingress 컨트롤러가 제공하는 사용자 정의 CRD를 사용할 것입니다.

Tags: