Kubernetes GatewayとIngress APIの比較
October 21, 2022
数ヶ月前、新しいKubernetes Gateway APIがベータ版に昇格しました。
安定したKubernetes Ingress APIと多数の実装があるのに、なぜ外部トラフィックを処理するための別のAPIが必要なのでしょうか?新しいGateway APIは、Ingress APIのどのような問題を解決するのでしょうか?これはIngress APIの終わりを意味するのでしょうか?
この記事では、これらのAPIを実際に触りながら、それらがどのように進化してきたのかを見ていくことで、これらの質問に答えようと思います。
サービスへの外部アクセスの標準化:Ingress API
Kubernetes Ingress APIは、Kubernetes内のサービスを外部トラフィックに公開することを標準化するために作成されました。Ingress APIは、ルーティングやSSL終端などの機能を導入することで、デフォルトのサービスタイプであるNodePort
とLoadBalancer
の制限を克服しました。
20以上のIngressコントローラーの実装が利用可能です。この記事では、Apache APISIXとそのIngressコントローラーを例として使用します。
APISIXや他のIngress実装を設定するために、Ingressリソースを作成できます。
以下の例は、APISIX Ingressを使用してアプリケーションの2つのバージョン間でトラフィックをルーティングする方法を示しています:
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
プレフィックスを持つリクエストをプレフィックスを削除してバックエンドにルーティングするIngressリソースが作成されます。例えば、/app/version
へのリクエストは/version
に転送されます。
アノテーションは選択したIngressコントローラーに固有です。これらの「独自の」拡張機能は、Ingress APIで当初意図されていた移植性の範囲を制限しました。
カスタムCRD > Ingress API
アノテーションに頼らざるを得ないことは、Ingressコントローラーの使いやすさも犠牲にします。
そのため、コントローラーはIngress APIの制限を克服するために独自のカスタムリソースを作成しました。以下の例は、APISIXのカスタムリソースを使用してアプリケーションの2つのバージョン間でトラフィックをルーティングする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 traffic rolloutを参照):
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オブジェクトに分離し、アプリケーション開発者とクラスターオペレーターに自律性を提供します。以下の図はこれを明確に説明しています:
これはIngress APIの終わりでしょうか?
Gateway APIは比較的新しく、その実装は常に変化しています。一方、Ingress APIは安定版リリースであり、時間の試練に耐えてきました。
もしあなたのユースケースが単純なルーティングのみを含み、追加機能を得るためにカスタムアノテーションを使用することに問題がない場合、Ingress APIはまだ堅実な選択肢です。
Gateway APIがIngress APIのスーパーセットであることを考えると、両方を統合することは理にかなっているかもしれません。SIG Networkコミュニティのおかげで、Gateway APIはまだ成長中であり、すぐに本番環境で使用できるようになるでしょう。
ほとんどのIngressコントローラーとサービスメッシュは、すでにIngress APIとともにGateway APIを実装しており、プロジェクトが進化するにつれて、さらに多くの実装が登場するでしょう。
個人的には、少なくとも今のところ、Ingress APIやGateway APIではなく、Apache APISIXのようなIngressコントローラーが提供するカスタムCRDを使用することを選ぶでしょう。