同じ Web サイトでも、/api へのアクセスは API 用のアプリへ、それ以外は画面を返すアプリへ送りたい。
Kubernetes でも、URL に応じた振り分けを設定できます。
これまで使われてきた Ingress と、より多くの設定や役割分担を扱う Gateway API を比べます。 最後に自分の振り分けルールを 1 つ作り、ブラウザーからアクセスして確かめます。
GOAL この章のゴール
- Ingress と Gateway API の設定・役割分担の違いが分かる
- 通信の入口と振り分けルールを別々に設定できる
- 自分のアプリへのルールを追加し、ブラウザーから開ける
Ingress の限界
たとえば example.com/api を API 用の Service へ送るには、ホスト名、パス、送り先を設定します。
この HTTP / HTTPS の振り分けルールを書くリソースが Ingressイングレスホスト名やパスに応じて、外部からの HTTP / HTTPS 通信を Service へ振り分けるルールを書くリソース。用語集で見る です。
設定の rules に host、path、backend を書くと、Ingress controller がそれを読み、実際のプロキシやロードバランサーに反映します。
ドキュメントは「Ingress リソースを作るだけでは何も起きず、Ingress controller が必要」とも書いています。
小さいことは長所でしたが、運用で必要になる項目の多くが入っていませんでした。
1 つ目の限界は、役割の曖昧さです。 基盤を運用する人は入口の LB 自体を管理したく、アプリの開発者は用意された LB に自分のサービスをつなぎたいのに、Ingress は 1 つのリソースで両方を書かせます。 IngressClass で実装を選べるようにはなりましたが、LB の管理とルーティングの規則は分けられません。
2 つ目は、足りない項目の逃げ場が annotation (リソースに付ける自由形式のメモ欄) だったことです。
公式ドキュメントは「Ingress controller は挙動の設定に annotation をよく使うので、選んだ controller のドキュメントでどの annotation が期待されるかを確認する」よう求めています。
パスの書き換え、タイムアウト、ALB のターゲット種別は、どれも nginx.ingress.kubernetes.io/… や alb.ingress.kubernetes.io/… といった実装固有の annotation で書きます。
annotation にはスキーマも検証も無く、別の Ingress controller に移すと全部書き直しになります。
Ingress API と ingress-nginx の保守は別の話
Ingress API は Kubernetes に残っていますが、その実装の一つであるコミュニティ版 ingress-nginx は 2026 年 3 月に保守を終了しました。 Kubernetes の公式告知は、終了後にバグ修正やセキュリティ更新を提供しないとしています。 Ingress の YAML が使えることと、それを読む controller の保守が続いていることは別に確認する必要があります。 NGINX Gateway Fabric は別のプロジェクトであり、名前に NGINX が含まれる製品をすべて同じ保守状況と考えることもできません。
Gateway API の役割分担
Gateway API は、SIG Network が Ingress の限界を踏まえて作り直した仕様です。 公式ドキュメントは設計の特徴を「役割指向 (role-oriented)」と呼び、3 つの役割を定義しています。 複数のクラスタを複数のテナントに提供する基盤を管理する Infrastructure Provider、ポリシーやネットワークアクセス、アプリの権限を管理する Cluster Operator、アプリの設定と Service の組み合わせを管理する Application Developer です。 3 つのリソースが、この役割に対応します。
- GatewayClass:公式ドキュメントの定義では「共通の設定と振る舞いを持つ Gateway の集合を定義する」cluster-scoped のリソース。
controllerNameに「このクラスの Gateway を管理する controller の名前」(この演習クラスタではio.cilium/gateway-controller) が入る。基盤の運用者が提供する。 - Gateway:「通信を処理する基盤のインスタンス」で、クラウドの LB やクラスタ内のプロキシを表す。ALB のリスナーに相当し、待ち受けるポートとプロトコル、ホスト名、どの namespace の Route を受け付けるか (
allowedRoutes) をlistenersに書く。既定では同じ namespace の Route しか受け付けない。クラスタ管理者が先に作っておく。 - HTTPRoute:「Gateway の listener から backend への HTTP リクエストの経路」を書く。
parentRefsで取り付け先の Gateway を指し、hostnamesとrulesのmatchesで一致条件を、backendRefsで Service を指す。開発者が自分の namespace に書く。gRPC には GRPCRoute、TLS の SNI で振り分けるなら TLSRoute、TCP / UDP のストリームには TCPRoute / UDPRoute がある。
Ingress では annotation だった項目 (ヘッダの書き換え、重み付け、リダイレクト、タイムアウト) は、HTTPRoute の filters や rules としてスキーマ付きで定義されています。
公式ドキュメントはこれを「Ingress ではカスタム annotation でしかできなかったヘッダによる振り分けや重み付けを表現できる」と説明しています。
実装を変えても HTTPRoute はそのまま使えます。
誰がプロキシや LB を作るのか
GatewayClass の controllerName は、Service の loadBalancerClass (第 9 章) と同じく、この Gateway を実装する controller を指します。
Gateway API の実装一覧には、Cilium、Envoy Gateway、GKE、Istio、AWS Load Balancer Controller、NGINX Gateway Fabric などが適合実装として並んでいます。
Cilium は Envoy (HTTP プロキシ) で Gateway を実装し、ドキュメントによれば「既定では Gateway ごとに type: LoadBalancer の Service を作る」構成です。
GKE は Cloud Load Balancing で、AWS Load Balancer Controller は L7 の Route を ALB、L4 の Route を NLB で実装します。
開発者が書く HTTPRoute は、どの実装でも同じです。
実装の対応範囲を調べる
Gateway API の公式実装一覧には、Envoy Gateway、Cilium、NGINX Gateway Fabric など、異なるデータプレーンや運用方法を持つ実装が並びます。 「Gateway API 対応」の一言で選ばず、使用する API のバージョン、Gateway と Mesh のどちらに対応するか、必要な Route と拡張機能の conformance report を確認します。 共通 API の試験に通ったことは、独自の認証設定や監視機能まで同じであることを意味しません。 この教材の Cilium で動いた設定を別の製品へ移すときも、この対応範囲を確認します。
演習クラスタの Gateway に HTTPRoute を取り付ける
演習クラスタには、kube-classroom が Gateway を用意しています。
kube-classroom-gateway namespace の tenant という Gateway は、listener http (port 80) で *.<あなたの ID>.kube.inductor.dev を受け、全 namespace からの Route を許可しています。
GatewayClass は kube-classroom です。
Cilium は既定だと Gateway ごとに type: LoadBalancer の Service を作りますが、第 9 章のとおりこのクラスタには LB を作る controller が居ません。
Cilium には GatewayClass の parametersRef から参照する CiliumGatewayClassConfig という CRD があり、spec.service.type で生成する Service の type を変えられます。
演習クラスタではこれで NodePort にしてあり、その NodePort に kube-classroom の cloudflared が外からの通信を流し込みます。
まず、用意されているものを確認します。
kubectl get gatewayclass
kubectl -n kube-classroom-gateway get gateway tenant -o yaml | yq '.spec.listeners, .status.conditions[] | select(.type=="Programmed")'
kubectl -n kube-classroom-gateway get svc出力例
NAME CONTROLLER ACCEPTED AGE
kube-classroom io.cilium/gateway-controller True 2h
- allowedRoutes:
namespaces:
from: All
hostname: '*.you.kube.inductor.dev'
name: http
port: 80
protocol: HTTP
status: "True"
type: Programmed
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-tenant NodePort 10.96.33.201 <none> 80:31234/TCP 2hcilium-gateway-tenant は、Cilium が Gateway のために作った Envoy の Service で、NodePort なのは CiliumGatewayClassConfig の効果です。
次に、第 5 章の web Service に向けて HTTPRoute を書きます。
hostnames は listener のワイルドカードに収まる名前にします。
ME=$(kubectl -n kube-classroom-gateway get gateway tenant -o jsonpath='{.spec.listeners[0].hostname}' | sed 's/^\*\.//')
echo "hostname suffix: $ME"
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web
spec:
parentRefs:
- name: tenant
namespace: kube-classroom-gateway
hostnames:
- web.$ME
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web
port: 80
EOF
kubectl get httproute web -o yaml | yq '.status.parents[0].conditions[] | {type, status, reason}'出力例
hostname suffix: you.kube.inductor.dev
type: Accepted
status: "True"
reason: Accepted
type: ResolvedRefs
status: "True"
reason: ResolvedRefsGateway API の仕様では、Accepted は「Route が Gateway に受け入れられたか拒否されたか」、ResolvedRefs は「controller が Route の参照先 (ここでは backendRefs の Service) を全て解決できたか」を表す条件です。
どちらも True なら、ブラウザで http://web.<あなたの ID>.kube.inductor.dev/ を開くと nginx の画面が出ます。
ターミナルからは、Gateway の Service にホスト名付きで送っても確認できます。
GW=$(kubectl -n kube-classroom-gateway get svc cilium-gateway-tenant -o jsonpath='{.spec.clusterIP}')
curl -s -o /dev/null -w '%{http_code}\n' -H "Host: web.$ME" "http://$GW/"
curl -s -o /dev/null -w '%{http_code}\n' -H "Host: other.$ME" "http://$GW/"出力例
200
404web. のホスト名は HTTPRoute に一致して nginx に届き、other. はどの Route にも一致しないので Envoy が 404 を返します。
クラスタ管理者が用意した Gateway に、開発者が HTTPRoute だけを足した形です。
kubectl delete httproute webこの Part のまとめ
Part 2 では、docker0 から始めて、ノードをまたぐ Pod ネットワーク、Service の ClusterIP の書き換え表、ELB からの経路、コンテナネイティブ LB、クラウド連携のコンポーネント、Gateway API まで追いました。
Pod の NIC は CNI プラグインが、ClusterIP の書き換え表は kube-proxy か Cilium が、LB は CCM や AWS Load Balancer Controller が、HTTP の入口は GatewayClass の controller が作っていました。
どれも Kubernetes 本体とは別のプログラムです。
Part 4 (インターフェース) では、この任せ方の取り決めそのものを扱います。
ふりかえり
QGateway API で開発者が書くリソースは?
GatewayClass は基盤運用者が実装として提供し、Gateway はクラスタ管理者がフロントエンドとして用意します。開発者は HTTPRoute で自分のサービスへの経路だけを書きます。
Q2026 年時点の Ingress の状況として正しいのは?
kubernetes.io は Ingress API が凍結されたと明記しています。GA の安定性保証は続き削除予定もありませんが、新機能は Gateway API 側にだけ入ります。
Q演習クラスタの Gateway の Service が NodePort なのはなぜ?
Cilium の既定は type: LoadBalancer ですが、第 9 章のとおりこのクラスタには Service controller が居ません。GatewayClass の parametersRef から CiliumGatewayClassConfig を参照して NodePort にし、kube-classroom 側の cloudflared がそこへ通信を届けています。
参考
-
Kubernetes ドキュメント「Gateway API」(役割指向の設計、GatewayClass、Gateway、HTTPRoute、allowedRoutes) https://kubernetes.io/docs/concepts/services-networking/gateway/
-
Kubernetes ドキュメント「Ingress」(定義、Ingress controller が必要、annotation、Ingress API の凍結) https://kubernetes.io/docs/concepts/services-networking/ingress/
-
Gateway API「API Overview」(各リソースと Route の種類、parentRefs と allowedRoutes) https://gateway-api.sigs.k8s.io/docs/concepts/api-overview/
-
Gateway API「Roles and personas」 https://gateway-api.sigs.k8s.io/docs/concepts/roles-and-personas/
-
Gateway API「Implementations」(適合実装の一覧) https://gateway-api.sigs.k8s.io/implementations/
-
Gateway API のリリース (v1.0.0: 2023 年 10 月、v1.6.0: 2026 年 6 月、TCPRoute / UDPRoute の GA) https://github.com/kubernetes-sigs/gateway-api/releases
-
Gateway API の型定義 (Accepted / ResolvedRefs / Programmed の条件、controllerName) https://github.com/kubernetes-sigs/gateway-api/blob/v1.6.0/apis/v1/shared_types.go
-
Cilium ドキュメント「Gateway API Support」(v1.6.1 対応、controllerName、LoadBalancer Service、CiliumGatewayClassConfig、Envoy) https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/
-
Cilium の CiliumGatewayClassConfig CRD (spec.service.type) https://github.com/cilium/cilium/blob/v1.20.2/pkg/k8s/apis/cilium.io/client/crds/v2alpha1/ciliumgatewayclassconfigs.yaml
-
AWS Load Balancer Controller「Gateway API」(L4 は NLB、L7 は ALB) https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/gateway/gateway/
-
Gateway API「Implementations」: https://gateway-api.sigs.k8s.io/docs/implementations/list/
-
Gateway API「Conformance」: https://gateway-api.sigs.k8s.io/docs/concepts/conformance/
-
Kubernetes「Ingress NGINX Retirement: What You Need to Know」: https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/
読み切ると称号を獲得
パケットの行き先を視る者
この Part を読み切りました。
称号一覧