Kubernetes Gateway API 간단히 살펴보기

Nicolas Fränkel

Nicolas Fränkel

September 7, 2022

Ecosystem

최근 블로그 포스트에서 Kubernetes 파드에 접근하는 여러 방법을 설명했습니다. 파드의 IP를 통해 접근할 수 있지만, 파드는 본질적으로 일시적입니다. 일반적인 방법은 Service를 구성하는 것입니다: Service의 IP는 안정적이며, Kubernetes의 역할은 Service와 그 아래의 파드 간의 매핑을 최신 상태로 유지하는 것입니다. 다양한 종류의 서비스가 있습니다: 내부 전용, 클러스터 외부에서 접근을 허용하는 NodePort, 그리고 일반적으로 클라우드 제공자에 의존하는 LoadBalancer가 있습니다. 마지막으로, 라우팅을 허용하는 Ingress 객체도 언급했습니다.

저는 의도적으로 새로운 주자인 Gateway API를 제외했습니다. 이번 포스트의 주제입니다.

Ingress에서 Gateway API로

Kubernetes 파드에 대한 외부 접근은 여러 진화 단계를 거쳤습니다. 예를 들어, IngressLoadBalancer의 라우팅 부재 문제에 대한 해결책입니다. Ingress의 가장 큰 문제는 "전용" 객체에 대한 의존성입니다. 상기하자면, Apache APISIX를 사용하여 라우팅을 생성하는 스니펫은 다음과 같습니다:

apiVersion: apisix.apache.org/v2beta3 #1
kind: ApisixRoute #1
metadata:
  name: apisix-route
spec:
  http:
    - name: left
      match:
        paths:
          - "/left"
      backends:
        - serviceName: left
          servicePort: 80
    - name: right
      match:
        paths:
          - "/right"
      backends:
        - serviceName: right
          servicePort: 80
  1. 전용 객체

전용 객체는 마이그레이션 시 문제가 됩니다. 한 제공자에서 다른 제공자로의 마이그레이션이 드물긴 하지만, 가능한 한 원활해야 합니다. 전용 객체를 사용할 때는 먼저 이전 객체를 새로운 객체로 매핑해야 합니다. 일대일 매핑이 아닐 가능성이 높습니다. 그런 다음, 사양을 새로운 모델로 번역해야 합니다: 이는 완전한 프로젝트가 될 가능성이 높습니다.

Gateway API의 아이디어는 표준 객체와 전용 구현 사이에 깔끔한 분리를 갖는 것입니다.

Gateway API

Gateway API는 SIG-NETWORK 커뮤니티에서 관리하는 오픈 소스 프로젝트입니다. 이는 Kubernetes에서 서비스 네트워킹을 모델링하는 리소스 모음입니다. 이러한 리소스 - GatewayClass, Gateway, HTTPRoute, TCPRoute, Service 등 -은 많은 벤더에 의해 구현되고 광범위한 산업 지원을 받는 표현적, 확장 가능하며 역할 지향적인 인터페이스를 통해 Kubernetes 서비스 네트워킹을 발전시키는 것을 목표로 합니다.

-- https://gateway-api.sigs.k8s.io

위 정의는 또한 조직적 문제를 언급합니다: 다른 역할은 다른 객체 집합을 관리해야 합니다.

Gateway API Model

이미지 출처: gateway-api.sigs.k8s.io

실제로, 클러스터 운영자와 개발자의 관심사는 상당히 다릅니다. 이는 과거의 Java EE 애플리케이션 서버와 매우 유사합니다. Java EE는 개발자, 배포자, 운영자 역할을 중심으로 구성된 사양을 제공했습니다. 개인적으로 가장 큰 차이점은 사양이 주로 개발자 경험에 초점을 맞추었다는 점입니다; 나머지는 구현자에게 달려 있었습니다. Gateway API는 모든 페르소나에 관심을 기울이는 것 같습니다.

Gateway API를 통해 파드 접근 구성

이전에 구성한 Ingress를 Gateway API로 대체해 보겠습니다. 여러 단계가 필요합니다.

새로운 Gateway CRD 설치

k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.0/standard-install.yaml

구현체 설치

저는 Apache APISIX를 사용할 것입니다. 또는 SIG 웹사이트에서 구현체 목록을 유지 관리합니다.

helm install apisix apisix/apisix \
  --namespace ingress-apisix \
  --create-namespace \
  --devel \                                                                #1
  --set gateway.type=NodePort \                                            #2
  --set gateway.http.nodePort=30800 \                                      #2
  --set ingress-controller.enabled=true \                                  #2
  --set ingress-controller.config.kubernetes.enableApiGateway=true \       #3
  --set ingressPublishService="ingress-apisix/apisix-gateway"              #4
  1. --devel 옵션 없이 Helm은 최신 릴리스를 설치하며, 이는 Gateway API와 작동하지 않습니다
  2. Gateway는 어쨌든 클러스터 외부에서 접근 가능해야 합니다
  3. 여기서 마법이 일어납니다!
  4. 나중에 다시 설명하겠습니다

모든 것이 작동하는지 확인해 보겠습니다:

k get all -n ingress-apisix
NAME                                             READY   STATUS    RESTARTS   AGE
pod/apisix-5fc9b45c69-cf42m                      1/1     Running   0          14m    #1
pod/apisix-etcd-0                                1/1     Running   0          14m    #2
pod/apisix-etcd-1                                1/1     Running   0          14m    #2
pod/apisix-etcd-2                                1/1     Running   0          14m    #2
pod/apisix-ingress-controller-6f8bd94d9d-wkzfn   1/1     Running   0          14m    #3

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
service/apisix-admin                ClusterIP   10.96.69.19     <none>        9180/TCP
service/apisix-etcd                 ClusterIP   10.96.226.79    <none>        2379/TCP,2380/TCP
service/apisix-etcd-headless        ClusterIP   None            <none>        2379/TCP,2380/TCP
service/apisix-gateway              NodePort    10.96.101.224   <none>        80:30800/TCP #4
service/apisix-ingress-controller   ClusterIP   10.96.141.230   <none>        80/TCP
  1. Apache APISIX 자체
  2. Apache APISIX는 etcd에 구성을 저장합니다. 차트는 기본적으로 세 개의 파드를 스케줄링하며, 이는 분산 시스템에서 장애를 처리하기 위한 좋은 관행입니다
  3. Apache APISIX 컨트롤러: Kubernetes 컨트롤러는 기존 상태를 원하는 상태로 이동시키는 제어 루프입니다
  4. Apache APISIX Gateway 서비스: Helm 차트를 통해 설치한 NodePort Service입니다. Helm 차트 설치 중 참조한 이름이기도 합니다 - ingressPublishService

이 시점에서 인프라는 준비되었습니다.

Gateway 구현 선언

위에서 언급했듯이, API는 사양과 구현 사이에 깔끔한 분리를 만듭니다. 그러나 이를 어떻게든 바인딩해야 합니다. 이는 GatewayClass 객체의 책임입니다:

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: GatewayClass #2
metadata:
  name: apisix-gateway-class #3
spec:
  controllerName: apisix.apache.org/gateway-controller #4
  1. Apache APISIX가 이 버전을 사용하므로 의도적으로 최신 버전을 사용하지 않습니다. (가까운) 미래에 발전할 것임을 알아두세요
  2. GatewayClass 객체
  3. 원하는 대로 이름을 지정하세요; 그러나 나중에 게이트웨이 클래스를 참조할 때 사용할 것입니다
  4. 컨트롤러의 이름은 구현에 따라 다릅니다. 여기서는 Apache APISIX의 것을 사용합니다.

GatewayClass는 클러스터 전체 범위를 가집니다. 이 모델을 통해 동일한 클러스터 내에서 다른 Gateway API 구현을 선언하고 병렬로 사용할 수 있습니다.

Gateway 생성

Apache APISIX를 사용하면 매우 간단합니다:

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: Gateway #2
metadata:
  name: apisix-gateway
spec:
  gatewayClassName: apisix-gateway-class #3
  listeners: #4
    - name: http
      protocol: HTTP
      port: 80
  1. 위와 동일한 네임스페이스
  2. Gateway 객체
  3. 이전에 선언한 게이트웨이 클래스를 참조합니다
  4. 클러스터 운영자가 원치 않는 사용을 피할 수 있도록 이 수준에서 일부 제한을 허용합니다

경고: Gateway API는 운영자 측에서 포트를 동적으로 변경하는 옵션을 지정합니다. 이 글을 쓰는 시점에서 Apache APISIX의 포트 할당은 _정적_입니다. 앞으로 동적으로 만들 계획입니다. 진행 상황을 따라가려면 GitHub 이슈를 구독하세요.

라우트, 라우트, 어디에나 라우트

지금까지 모든 것이 인프라였습니다; 이제 라우팅을 구성할 수 있습니다.

이전 포스트와 동일한 라우팅을 원합니다; /left 분기와 right 분기입니다. 간결함을 위해 후자는 생략하겠습니다.

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: HTTPRoute #2
metadata:
  name: left
spec:
  parentRefs:
    - name: apisix-gateway #3
  rules:
    - matches: #4
        - path: #4
            type: PathPrefix #4
            value: /left
      backendRefs: #5
        - name: left #5
          port: 80 #5
  1. 위와 동일한 네임스페이스
  2. HTTPRoute 객체
  3. 위에서 생성한 Gateway를 참조합니다
  4. 규칙 일치. 우리의 경우 경로 접두사에 대해 일치하지만, 많은 규칙이 사용 가능합니다. 쿼리 매개변수, 헤더 등에 따라 일치시킬 수 있습니다.
  5. 전달할 "업스트림". 이전 블로그 포스트에서 left Service를 정의했습니다.

작동 확인

이제 라우트를 구성했으므로 작동하는지 확인할 수 있습니다.

curl localhost:30800/left

Helm 차트를 설치할 때 Apache APISIX가 30800 포트에 NodePort 서비스를 생성하도록 지시했습니다. 따라서 클러스터 외부에서 서비스에 접근하기 위해 이 포트를 사용할 수 있습니다.

left

결론

클러스터 외부에서 파드에 접근하는 데 사용할 수 있는 많은 대안이 있습니다. CNCF는 대부분의 경우 이전의 것을 개선하기 위해 추가했습니다.

Gateway API는 이와 관련된 최신 제안입니다. 사양은 진행 중이며 제품은 구현의 다른 단계에 있습니다. 이러한 이유로, 프로덕션을 API에 기반하는 것은 아직 이릅니다. 그러나 이전 접근 방식에 비해 상당한 개선이 될 것이므로 진행 상황을 따라가는 것이 좋습니다.

이 포스트의 전체 소스 코드는 GitHub에서 찾을 수 있습니다.

더 알아보기:

Tags: