Kubernetes Gateway API の概要
September 7, 2022
私の最近のブログ記事では、KubernetesのPodにアクセスするためのいくつかの方法について説明しました。PodのIPを通じてアクセスすることもできますが、Podは本質的に一時的なものです。標準的な方法は、Service
を設定することです。Service
のIPは安定しており、Kubernetesの仕事は、Service
とその基盤となるPodのマッピングを最新の状態に保つことです。利用可能なサービスの種類はいくつかあります:クラスタ内のみのアクセスを許可するもの、外部からのアクセスを許可するNodePort
、そして一般的にはクラウドプロバイダが提供するサードパーティのコンポーネントに依存するLoadBalancer
です。最後に、ルーティングを許可するIngress
オブジェクトについても触れました。
私は意図的に、新たに登場したGateway APIについて触れませんでした。それがこの記事の主題です。
IngressからGateway APIへ
KubernetesのPodへの外部アクセスは、いくつかの進化のステップを経てきました。例えば、Ingress
はLoadBalancer
にルーティング機能が欠けている問題に対する答えです。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のマッピングではない可能性があります。その後、仕様を新しいモデルに翻訳する必要があります。これは本格的なプロジェクトになる可能性があります。
Gateway APIの背後にある考え方は、標準オブジェクトとプロプライエタリな実装を明確に分離することです。
Gateway API
Gateway APIは、SIG-NETWORKコミュニティによって管理されているオープンソースプロジェクトです。これは、Kubernetesのサービスネットワーキングをモデル化するリソースのコレクションです。これらのリソース -
GatewayClass
、Gateway
、HTTPRoute
、TCPRoute
、Service
など - は、多くのベンダーによって実装され、広範な業界のサポートを持つ表現力豊かで拡張可能なロール指向のインターフェースを通じて、Kubernetesのサービスネットワーキングを進化させることを目的としています。
上記の定義は、組織的な懸念も言及しています:異なるロールが異なるオブジェクトのセットを管理するべきです。
画像は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
--devel
オプションなしでは、HelmはGateway APIと互換性のない最新リリースをインストールします- とにかく、Gatewayはクラスタ外からアクセス可能である必要があります
- ここで魔法が起こります!
- 後でこれに戻ります
すべてが機能しているか確認しましょう:
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
- Apache APISIX自体
- Apache APISIXはその設定を
etcd
に保存します。チャートはデフォルトで3つのPodをスケジュールします。これは分散システムでの障害に対処するための良いプラクティスです - Apache APISIXコントローラ:Kubernetesコントローラは、既存の状態を望ましい状態に向かって動かす制御ループです
- 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
- Apache APISIXがこのバージョンを使用しているため、意図的に最新バージョンを使用していません。近い将来に進化することを意識してください
GatewayClass
オブジェクト- 好きなように名前を付けてください。ただし、後でゲートウェイクラスを参照するために使用します
- コントローラの名前は実装に依存します。ここでは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
- 上記と同じ名前空間
Gateway
オブジェクト- 以前に宣言したゲートウェイクラスを参照
- このレベルでいくつかの制限を許可することで、クラスタオペレータは望ましくない使用を避けることができます
警告: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
- 上記と同じ名前空間
HTTPRoute
オブジェクト- 上記で作成した
Gateway
を参照 - ルールマッチ。この場合、パスのプレフィックスに基づいてマッチしますが、多くのルールが利用可能です。クエリパラメータやヘッダーに基づいてマッチすることもできます。
- 転送する「アップストリーム」。前のブログ記事で
left
Service
を定義しました。
動作確認
ルートを設定したので、動作を確認できます。
curl localhost:30800/left
Helmチャートをインストールした際に、Apache APISIXに30800
ポートでNodePort
サービスを作成するように指示しました。したがって、このポートを使用してクラスタ外からサービスにアクセスできます。
left
結論
クラスタ外からPodにアクセスするための多くの代替手段があります。CNCFは、以前のものを改善するためにそれらのほとんどを追加しました。
Gateway APIは、この点において最新の提案です。仕様は進行中であり、製品は実装の異なる段階にあります。このため、APIを基盤に本番環境を構築するにはまだ早すぎます。しかし、以前のアプローチを大幅に改善する可能性があるため、進捗を追跡するべきです。
この記事の完全なソースコードはGitHubにあります。
さらに進むために: