Kubernetes Gateway API の概要

Nicolas Fränkel

Nicolas Fränkel

September 7, 2022

Ecosystem

私の最近のブログ記事では、KubernetesのPodにアクセスするためのいくつかの方法について説明しました。PodのIPを通じてアクセスすることもできますが、Podは本質的に一時的なものです。標準的な方法は、Serviceを設定することです。ServiceのIPは安定しており、Kubernetesの仕事は、Serviceとその基盤となるPodのマッピングを最新の状態に保つことです。利用可能なサービスの種類はいくつかあります:クラスタ内のみのアクセスを許可するもの、外部からのアクセスを許可するNodePort、そして一般的にはクラウドプロバイダが提供するサードパーティのコンポーネントに依存するLoadBalancerです。最後に、ルーティングを許可するIngressオブジェクトについても触れました。

私は意図的に、新たに登場したGateway APIについて触れませんでした。それがこの記事の主題です。

IngressからGateway APIへ

KubernetesのPodへの外部アクセスは、いくつかの進化のステップを経てきました。例えば、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. プロプライエタリなオブジェクト

プロプライエタリなオブジェクトは、移行時に問題となります。あるプロバイダから別のプロバイダへの移行はおそらく稀ですが、可能な限りシームレスであるべきです。プロプライエタリなオブジェクトを使用する場合、まず古いオブジェクトから新しいオブジェクトへのマッピングが必要です。1対1のマッピングではない可能性があります。その後、仕様を新しいモデルに翻訳する必要があります。これは本格的なプロジェクトになる可能性があります。

Gateway APIの背後にある考え方は、標準オブジェクトとプロプライエタリな実装を明確に分離することです。

Gateway API

Gateway APIは、SIG-NETWORKコミュニティによって管理されているオープンソースプロジェクトです。これは、Kubernetesのサービスネットワーキングをモデル化するリソースのコレクションです。これらのリソース - GatewayClassGatewayHTTPRouteTCPRouteServiceなど - は、多くのベンダーによって実装され、広範な業界のサポートを持つ表現力豊かで拡張可能なロール指向のインターフェースを通じて、Kubernetesのサービスネットワーキングを進化させることを目的としています。

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

上記の定義は、組織的な懸念も言及しています:異なるロールが異なるオブジェクトのセットを管理するべきです。

Gateway API Model

画像はgateway-api.sigs.k8s.ioから

確かに、クラスタオペレータと開発者の懸念はかなり異なります。これは、古いJava EEアプリケーションサーバーに似ています。Java EEは、開発者、デプロイヤー、オペレータというロールを中心に組織された仕様を提供していました。私の意見では、最も大きな違いは、仕様が主に開発者エクスペリエンスに焦点を当てていたことです。残りは実装者に任されていました。Gateway APIは、すべてのペルソナに関心を持っているようです。

Gateway APIを介したPodアクセスの設定

以前に設定した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つのPodをスケジュールします。これは分散システムでの障害に対処するための良いプラクティスです
  3. Apache APISIXコントローラ:Kubernetesコントローラは、既存の状態を望ましい状態に向かって動かす制御ループです
  4. Apache APISIX Gatewayサービス:これはHelm Chartを介してインストールしたNodePort Serviceです。Helm Chartインストール時に参照した名前でもあります - 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 issueを購読してください。

ルート、ルート、どこでもルート

これまではすべてインフラストラクチャでした。ようやくルーティングを設定できます。

前の記事と同じルーティングを設定したいと思います。/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

結論

クラスタ外からPodにアクセスするための多くの代替手段があります。CNCFは、以前のものを改善するためにそれらのほとんどを追加しました。

Gateway APIは、この点において最新の提案です。仕様は進行中であり、製品は実装の異なる段階にあります。このため、APIを基盤に本番環境を構築するにはまだ早すぎます。しかし、以前のアプローチを大幅に改善する可能性があるため、進捗を追跡するべきです。

この記事の完全なソースコードはGitHubにあります。

さらに進むために:

Tags: