Gateway APIは、Kubernetesクラスタへの入口をGatewayClass・Gateway・HTTPRouteという複数のリソースに分けて書く、Kubernetes公式の標準APIです。Ingressは仕様の更新が止まり、Kubernetesプロジェクトは後継としてGateway APIを推奨しています。この記事では2026年10月時点の最新安定版v1.6.3を前提に、Ingressとの違い、HTTPRouteで公開するまでのYAML、重み付けと別namespace参照、ingress2gatewayでの移行手順、移るべき条件の線引きを扱います。
まとめ:Gateway APIは入口と経路を別リソースに分けたIngressの後継
Gateway APIは製品名ではなく、Kubernetesの拡張API(CRD)の名前です。入口の種類をGatewayClass、待ち受けをGateway、URLごとの振り分けをHTTPRouteに書き分けるので、インフラ担当とアプリ担当が別々のリソースを持てます。Ingressではアノテーション頼みだった重み付け分割やヘッダー条件も、標準のフィールドで書けます。
新規クラスタと、2026年3月に退役したingress-nginxを使っているクラスタは、Gateway APIを選ぶのが妥当です。CRDはStandardチャネルを入れ、実装はv1.6適合のものから選びます。移行はingress2gatewayで下書きを作り、新旧を並行稼働させてからDNSを切り替えます。
Gateway APIの3リソースと役割分担をIngressとの違いから整理する
用語の混同が最も多いので、名称の整理から入ります。
AWSのAPI Gatewayとは別物のKubernetes標準APIという位置づけ
「gateway api」で検索すると、Amazon API Gatewayの情報も混ざります。Amazon API GatewayはAPIの公開・認証・流量制限を受け持つAWSのマネージドサービスで、Kubernetesとは関係なく使えるサービスです。一般的なAPIゲートウェイ製品の役割はAPIゲートウェイの役割とリバースプロキシとの違いで整理しています。
一方、Kubernetes Gateway APIは、SIG Networkが開発するgateway.networking.k8s.ioグループのAPIです。Kubernetes公式ドキュメントのGateway APIの章が説明するとおり、クラスタ外からの通信をServiceへ届ける設定を宣言するもので、それ自体は通信を中継しません。実際に通信をさばくのは、Envoy GatewayやCiliumなどの実装(コントローラー)です。
GatewayClass・Gateway・HTTPRouteを3つの役割で受け持つ構造
公式のAPI Overviewは、利用者をインフラ提供者・クラスタ運用者・アプリ開発者の3つのロールに分け、それぞれが持つリソースを決めています。
| リソース | スコープ | 主な持ち主 | 書く内容 |
|---|---|---|---|
| GatewayClass | クラスタ全体 | インフラ提供者 | どのコントローラーが処理するか |
| Gateway | namespace | クラスタ運用者 | ポート・プロトコル・証明書・許可Route |
| HTTPRoute | namespace | アプリ開発者 | ホスト名・パス・ヘッダー条件と転送先Service |
GatewayClassはStorageClassに近い位置づけで、1つのコントローラーが受け持ちます。HTTPRouteがGatewayに結び付くには、Route側のparentRefsでGatewayを指し、Gateway側のlistenerがそのRouteを許可している必要があります。許可の範囲はallowedRoutes.namespacesのSame(既定)・All・Selectorの3通りです。
Ingressのアノテーション依存とGateway APIが標準化した機能の差
Ingressは1つのリソースに入口と振り分けを同居させ、標準で書けるのはホスト名とパスによるHTTP振り分けとTLS終端までです。重み付けやヘッダー条件はコントローラー独自のアノテーションで補うため、コントローラーを替えると設定を書き直すことになります。
| やりたいこと | Ingress | Gateway API(Standard) |
|---|---|---|
| 重み付けの分割 | 実装のアノテーション | backendRefsのweight |
| ヘッダー条件の振り分け | 実装のアノテーション | matchesのheaders |
| リダイレクト・パス書き換え | 実装のアノテーション | リダイレクト・URL書き換え |
| gRPC・TCP・UDP | 標準では扱えない | gRPC・TCP・UDPの各Route |
| 別namespaceのServiceへ転送 | 標準では扱えない | ReferenceGrantで許可 |
リダイレクトとパス書き換えはfiltersのRequestRedirect・URLRewriteに記述します。gRPC・TCP・UDPに対応するリソース名は、それぞれGRPCRoute・TCPRoute・UDPRouteです。
Ingressの公式ページは、Ingress APIを「frozen」とし、今後は変更も更新も加えないと明記しています。ただし削除の予定は無く、既存のIngressがすぐに動かなくなるわけではありません。Service・Ingressを含むクラスタ内通信の全体像はKubernetesネットワーク設計の解説にまとめています。
v1.6系のStandardとExperimentalの範囲と実装の適合状況を確かめる
Gateway APIはKubernetes本体とは別に版を重ねます。機能ごとの版と実装の対応範囲を先に確かめれば、YAMLが反映されない事態を防げます。
v1.0からv1.7rcまでに標準チャネルへ昇格した機能の時系列
GitHubのリリースノートから、Standardチャネル(GA)に入った主な機能を版ごとに並べます。
| 版 | 公開日 | Standardに入った主な機能 |
|---|---|---|
| v1.0.0 | 2023-10-31 | 入口の3リソースがv1 |
| v1.1.0 | 2024-05-09 | GRPCRoute、サービスメッシュ対応 |
| v1.4.0 | 2025-10-06 | バックエンドTLS・対応機能の提示 |
| v1.5.0 | 2026-02-27 | リスナー共有・CORS・TLSと参照許可のv1 |
| v1.6.0 | 2026-06-29 | TCPRoute・UDPRouteがv1 |
| v1.7.0-rc.3 | 2026-10-23 | HTTPRouteのretry(候補版) |
表のv1.0.0でv1になった3リソースはGatewayClass・Gateway・HTTPRouteです。v1.4.0の項目はBackendTLSPolicyとSupportedFeaturesを指します。v1.5.0ではListenerSet、CORSフィルタ、TLSRoute v1、ReferenceGrant v1がStandardに入りました。
2026年10月25日時点の最新安定版はv1.6.3(2026-10-06公開)です。v1.7.0-rc.3はまだ候補版なので、retryを本番で使うのはv1.7.0の正式版と実装側の対応を待ってからにします。
StandardとExperimentalのCRDを混在させないための安全装置
CRDは、GA機能だけを含むstandard-install.yamlと、試験中の機能も含むexperimental-install.yamlの2種類が配布されています。公式のVersioningページは、Experimentalのフィールドやリソースが予告なく変わりうるとしています。
v1.5.0のリリースノートによると、v1.5からはsafe-upgrades.gateway.networking.k8s.ioというValidatingAdmissionPolicyが同梱されます。Standardを入れた後にExperimentalを入れる操作と、v1.5より前への戻しを拒否する仕組みです。本番はStandardだけにし、Experimentalは検証クラスタで試せば、この拒否に当たりません。TLSRouteのCEL検証にはKubernetes 1.31以上が要ります。
適合レポートで見るEnvoy Gateway・Cilium・Istioなどの実装状況
Gateway APIはAPIの定義だけなので、実装を1つ選んで入れる必要があります。公式のImplementationsページでは、2026年10月25日時点で次の実装がv1.6の適合(Conformant)として掲載されています。
- Envoy Gateway・kgateway・Traefik Proxy・Cilium(v1.6.1)
- NGINX Gateway Fabric(v1.6.3)
- Istio・Google Kubernetes Engine(v1.6.0)
- AWS Load Balancer Controller(v1.6.1、ただしPartially Conformant)
EKSでALBを入口にする構成は、一部の機能が未対応の可能性を前提に、使うフィールドを実装のドキュメントで1つずつ確かめます。Istioを入れているクラスタなら、別のコントローラーを足さずにIstioのゲートウェイで処理できる構成です。その書き方はIstio GatewayでGateway APIを使う設定で扱っています。
CRDの導入からGatewayとHTTPRouteで公開するまでの手順を試す
ここからは、実装にEnvoy Gatewayを使う例で、CRDの導入から外部公開の確認までを通します。GatewayClassのcontrollerName以外は、どの実装でも同じYAMLです。
v1.6.3のStandard CRDをサーバー側で適用する導入手順
公式のGetting startedは、CRDを--server-side付きで適用する手順を示しています。多くの実装はHelmチャートでCRDも一緒に入れるため、実装の手順と二重に入れないよう先に確認します。
# Gateway API v1.6.3 の Standard チャネルの CRD を入れる
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.3/standard-install.yaml
# 入った CRD を確かめる(gatewayclasses・gateways・httproutes・referencegrants など)
kubectl get crd | grep gateway.networking.k8s.io
# 実装の例:Envoy Gateway v1.9.2 を Helm で入れる
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.9.2 -n envoy-gateway-system --create-namespace
Envoy GatewayのコマンドはEnvoy GatewayのQuickstartの記載どおりです。CRDはapplyをdeleteに替えれば消せますが、使用中のときや実装が入れたCRDは消さないよう公式が注意しています。
GatewayClassとGatewayで待ち受けと名前空間の許可を書く例
GatewayはインフラのnamespaceにGatewayを1つ置き、アプリのnamespaceからRouteを結び付ける共有型にします。ラベルshared-gateway-access: "true"を付けたnamespaceのRouteだけを受け入れる設定です。
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: shared-gw
namespace: infra
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
shared-gateway-access: "true"
allowedRoutesを省くと、同じnamespaceのRouteしか結び付きません。アプリのnamespaceにRouteを置いたのに反映されないときは、最初にここを疑います。
HTTPRouteで親Gatewayと転送先Serviceを指定する設定例
アプリ側は、GatewayをparentRefsで指し、条件に合う通信をbackendRefsのServiceへ送るHTTPRouteを書きます。公式のHTTP routingガイドと同じ構成です。
kubectl label namespace app shared-gateway-access=true
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api
namespace: app
spec:
parentRefs:
- name: shared-gw
namespace: infra
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v1
backendRefs:
- name: api
port: 8080
RouteとGatewayのnamespaceが違うので、parentRefsのnamespaceは省略できません。listenerにhostnameを書いた場合は、Routeのhostnamesと1つ以上重なっていないと結び付かない点にも気を付けます。
kubectl getで受理とプログラム反映のstatusを確認する手順
反映の確認は、Gatewayとルートのstatusに出る条件(conditions)を読むのが確実です。
kubectl get gateway -n infra shared-gw
# PROGRAMMED が True で、ADDRESS に外部 IP かホスト名が入れば待ち受け開始
kubectl get httproute -n app api -o jsonpath='{.status.parents[*].conditions}'
# Accepted=True と ResolvedRefs=True を確かめる
export GATEWAY_HOST=$(kubectl get gateway -n infra shared-gw -o jsonpath='{.status.addresses[0].value}')
curl -H "Host: api.example.com" "http://$GATEWAY_HOST/v1/"
GatewayのAcceptedがFalseならGatewayClassの名前かコントローラーの起動を、HTTPRouteのAcceptedがFalseならallowedRoutesとホスト名の重なりを見直します。ResolvedRefsがFalseのときは、転送先のService名・ポートの誤りか、次の章で扱う別namespace参照の許可漏れです。
HTTPRouteの重み付け分割とReferenceGrantによる別名前空間参照
Ingressでは実装ごとに書き方が違った段階的な切り替えと、namespaceをまたぐ転送を、標準のフィールドで書きます。
backendRefsのweightで90対10のカナリアを組む設定と切り戻し
公式のHTTP traffic splittingガイドのとおり、1つのルールに複数のServiceを並べ、weightで比率を指定します。weightは割合ではなく相対値で、合計が分母になります。省略時の値は1です。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api
namespace: app
spec:
parentRefs:
- name: shared-gw
namespace: infra
hostnames:
- "api.example.com"
rules:
- backendRefs:
- name: api-v1
port: 8080
weight: 90
- name: api-v2
port: 8080
weight: 10
切り替えを終えるときはapi-v1を0、api-v2を1にし、問題が出たら値を戻せば旧版へ切り戻せます。Deploymentの入れ替えそのものに使うKubernetesのローリングアップデートはPod単位で切り替わるため、利用者の一部だけに新版を見せたい場合はこの重み付けを使います。
別名前空間のService参照を許可するReferenceGrantの配置先
HTTPRouteから別namespaceのServiceへ転送するには、参照される側のnamespaceにReferenceGrantを置きます。公式のReferenceGrantリファレンスによると、ReferenceGrantは自分と同じnamespaceのリソースへの参照しか許可できません。Gatewayが別namespaceの証明書Secretを参照する場合も同じ仕組みです。
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-app-routes
namespace: backend
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: app
to:
- group: ""
kind: Service
このReferenceGrantが無いと、HTTPRouteのResolvedRefsは理由RefNotPermittedでFalseになり、通信は転送されません。許可の向きを逆に書くミスが多いので、置き場所は転送先のnamespaceと覚えておくと迷いません。
ingress2gatewayでIngressからGateway APIへ移行する手順
既存のIngressを手で書き直す前に、公式の変換ツールで下書きを作ると作業量が見えます。ingress-nginx固有のアノテーションの書き換えと移行先の選び方は、ingress-nginxの退役と移行先の比較で詳しく扱っています。
ingress2gateway 1.0のprintで変換結果を確かめるコマンド
Kubernetes公式ブログのIngress2Gateway 1.0リリース記事によると、1.0ではCORS・バックエンドTLS・正規表現マッチ・パスの書き換えなど30以上のingress-nginxアノテーションに対応しました。1.0より前の対応は3つだけでした。
# Homebrew で入れる(GitHub のリリースからバイナリも取得できる)
brew install ingress2gateway
# namespace 単位で変換し、結果をファイルに出す(クラスタは変更しない)
ingress2gateway print --namespace my-api --providers=ingress-nginx > gwapi.yaml
# 実装固有の拡張も出したい場合(envoy-gateway・kgateway・agentgateway)
ingress2gateway print --namespace my-api --providers=ingress-nginx --emitter envoy-gateway > gwapi-eg.yaml
printは変換結果を表示するだけで、クラスタには適用しません。変換できない設定には警告が出るため、出力とログの確認が必要です。たとえばconfiguration-snippetは未対応の警告になり、正規表現パスには大文字小文字を区別しない(?i)が付きます。ツールの更新状況はingress2gatewayのGitHubリポジトリで追えます。
新旧の入口を並行稼働させて応答を検証しDNSを切り替える移行の段取り
Gatewayは新しいロードバランサーとIPを持つため、Ingressを消してから作り直すと停止時間が出ます。GKEの移行ガイドも、新旧を並行稼働させて検証してからDNSを切り替える方法を示しています。
- Gateway API のCRDと実装を入れ、Gatewayを作って外部アドレスが付くのを待つ
- ingress2gatewayの出力を見直してHTTPRouteを適用し、Ingressは残したままにする
- 新しいGatewayのアドレスへHostヘッダー付きのcurlを送り、全パスの応答を旧経路と突き合わせる
- DNSのTTLを短くしてから、レコードを新しいGatewayのアドレスへ切り替える
- 旧経路への通信が止まったのをアクセスログで確かめてから、Ingressとコントローラーを消す
手順3で差が出やすいのは、パスの前方一致・末尾スラッシュ・タイムアウトの扱いです。旧コントローラーの既定値に依存していた挙動は、HTTPRouteに書かない限り再現されません。
Gateway APIを採用する条件と見送ってIngressを残す場面の線引き
判断は、クラスタの新旧と、今のIngressコントローラーに保守の見込みがあるかで決まります。
新規クラスタと退役したingress-nginx利用中はGateway APIを選ぶ
新規クラスタはGateway APIを選びます。Ingressには新機能が入らず、アノテーションで書いた設定は実装を替えるたびに書き直しになるからです。
ingress-nginxを使っているクラスタも移行の対象です。Kubernetes公式ブログの退役告知のとおり、ingress-nginxは2026年3月で保守を終え、以後は脆弱性が見つかっても修正版は出ません。入口のコンポーネントは外部から直接届くので、修正の出ない状態で運用を続けるのは避けるべきです。移行の設計や、EKS・GKEでのロードバランサー構成から相談したい場合は、クラウドのインフラ構築支援で入口の作り替えも含めて対応しています。
単一サービスの小規模構成でGateway APIへの移行が過剰になる条件
次の条件がすべてそろうなら、急いで移らずIngressのままで構いません。
- 保守が続いているコントローラー(クラウド事業者のIngressコントローラーなど)を使っている
- 公開するServiceが1〜2個で、ホスト名とパスの振り分けだけで足りている
- 重み付け分割・ヘッダー条件・gRPCの振り分けを使う予定が無い
この構成で移っても変わるのはYAMLの書き方だけで、ロードバランサーの費用とDNS切り替えの手間が増えます。条件のどれかが崩れた時点か、クラスタを作り直す時点を移行の期限にします。
Gateway APIの導入と移行についてよくある質問と回答
導入前の検討でよく挙がる疑問に、公式ドキュメントの記載をもとに答えます。
Gateway APIとIngressは同じクラスタで併用できますか?
併用できます。IngressとGateway APIは別のリソースで、それぞれのコントローラーが独立して処理します。同じホスト名を両方に書いた場合、応答するのはDNSが向いている側だけです。切り替え時に備え、どちらが応答したかをアクセスログで見分けられるようにしておきます。
Kubernetes Gateway APIとAmazon API Gatewayは何が違いますか?
Amazon API GatewayはAPIの公開・認証・流量制限を受け持つAWSのマネージドサービスです。Kubernetes Gateway APIはクラスタの入口を宣言するAPI定義で、比較して選ぶ関係ではありません。EKSでAmazon API Gatewayを前段に置き、その後ろをGateway APIで振り分ける構成もとれます。
Gateway APIが出たことでIngressは廃止されますか?
廃止はされません。凍結されたのはIngress APIの開発で、既存のIngressは今後も動きます。退役したのはingress-nginxという特定のコントローラーです。ingress-nginxを使っているなら、Ingressのまま別のコントローラーへ移るか、Gateway APIへ移るかを決める必要があります。
Gateway APIの実装はどれを選べばよいですか?
まず公式のImplementationsページで、使う版に適合(Conformant)しているかを確かめます。そのうえで、既にIstioやCiliumを使っているならそれを入口にも使い、GKEならGKEのGatewayコントローラーを使えば部品が増えません。どれも使っていなければ、Envoy GatewayかNGINX Gateway Fabricが候補です。
ExperimentalチャネルのCRDを本番環境で使ってよいですか?
本番では避けます。Experimentalのフィールドは版の間で名前や型が変わり、v1.7.0-rc.1でもセッション維持の設定項目が改名されました。必要な機能がExperimentalにしか無いなら、検証クラスタで試しながらStandardへの昇格を待つ進め方が安全です。
関連記事
- NGINX Ingressとは?退役したingress-nginxとF5版の違い・移行判断:ingress-nginxからの移行先の比較とアノテーションの書き換え
- Kubernetesネットワーク設計|Service・Ingress・Pod間通信とCNI選定の実装判断:入口を含むクラスタ内通信の全体設計
- Istio Gatewayの設定方法:Ingress GatewayのYAML・TLS終端・Gateway API対応【1.31系】:IstioをGateway APIの実装として使う場合の設定
- APIゲートウェイとは?役割・機能とリバースプロキシ/サービスメッシュとの違い・導入判断を解説:名前が似たAPIゲートウェイ製品の役割
- Kubernetes(クバネティス)とは?メリット・デメリットと仕組み、Dockerとの違いを解説:Kubernetes自体の仕組みの前提知識