Kubernetes Gateway API完全ガイド
Kubernetes Gateway APIは、従来のIngressを置き換える次世代のルーティングAPIです。より表現力が高く、ロールベースで、ベンダー拡張にも対応した設計になっています。本記事では、Gateway APIの基本概念から実践的な実装例、TLS設定、トラフィック分割まで徹底的に解説します。
Gateway APIとは
Gateway APIは、Kubernetesクラスタへの外部トラフィックをルーティングするための新しいAPIセットです。IngressとService meshの中間に位置し、より柔軟で強力な機能を提供します。
従来のIngressとの違い
# 従来のIngress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
# Gateway API
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /app
backendRefs:
- name: app-service
port: 80
主な利点
- ロールベースの設計: インフラ管理者とアプリ開発者の責務を分離
- 表現力の向上: より複雑なルーティングロジックが可能
- ポータビリティ: ベンダー固有のアノテーションが不要
- 拡張性: カスタムリソースで機能を拡張可能
- 型安全: アノテーションではなく、構造化されたフィールド
Gateway APIの主要コンセプト
Gateway APIは、3つの主要なリソースで構成されています。
GatewayClass
GatewayClassは、ゲートウェイの実装を定義します。インフラ管理者が管理します。
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway-class
spec:
controllerName: nginx.org/gateway-controller
description: "NGINX Gateway Controller"
parametersRef:
group: gateway.nginx.org
kind: NginxGateway
name: nginx-config
主要なGatewayClass実装:
- NGINX Gateway Fabric: nginx.org/gateway-controller
- Istio: istio.io/gateway-controller
- Envoy Gateway: gateway.envoyproxy.io/gatewayclass-controller
- Kong: konghq.com/gateway-controller
- Traefik: traefik.io/gateway-controller
Gateway
Gatewayは、実際のロードバランサーやプロキシインスタンスを表します。インフラ管理者が管理します。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: default
spec:
gatewayClassName: nginx-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: example-tls-secret
allowedRoutes:
namespaces:
from: All
HTTPRoute
HTTPRouteは、HTTPトラフィックのルーティングルールを定義します。アプリケーション開発者が管理します。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
namespace: default
spec:
parentRefs:
- name: example-gateway
hostnames:
- "example.com"
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-service
port: 80
実践的な実装例
基本的なHTTPルーティング
# GatewayClassの作成(クラスタ管理者)
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: nginx.org/gateway-controller
---
# Gatewayの作成(インフラ管理者)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: gateway-system
spec:
gatewayClassName: nginx-gateway
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
---
# HTTPRouteの作成(アプリ開発者)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
namespace: my-app
spec:
parentRefs:
- name: production-gateway
namespace: gateway-system
hostnames:
- "myapp.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api/v1
backendRefs:
- name: api-v1-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /api/v2
backendRefs:
- name: api-v2-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-service
port: 3000
パスベースルーティング
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: path-based-routing
spec:
parentRefs:
- name: production-gateway
hostnames:
- "services.example.com"
rules:
# 完全一致
- matches:
- path:
type: Exact
value: /admin
backendRefs:
- name: admin-service
port: 8080
# プレフィックス一致
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
# 正規表現一致
- matches:
- path:
type: RegularExpression
value: /user/[0-9]+
backendRefs:
- name: user-service
port: 8080
# デフォルトルート
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: default-service
port: 80
ヘッダーベースルーティング
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-based-routing
spec:
parentRefs:
- name: production-gateway
hostnames:
- "api.example.com"
rules:
# APIバージョンヘッダーでルーティング
- matches:
- headers:
- name: X-API-Version
value: "v2"
backendRefs:
- name: api-v2-service
port: 8080
# デフォルト(v1)
- matches:
- headers:
- name: X-API-Version
value: "v1"
backendRefs:
- name: api-v1-service
port: 8080
# カナリアデプロイ用
- matches:
- headers:
- name: X-Canary
value: "true"
backendRefs:
- name: canary-service
port: 8080
クエリパラメータベースルーティング
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-based-routing
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- queryParams:
- name: version
value: "beta"
backendRefs:
- name: beta-service
port: 8080
- matches:
- queryParams:
- name: version
value: "stable"
backendRefs:
- name: stable-service
port: 8080
TLS設定
HTTPS終端
# TLS証明書のSecretを作成
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: gateway-system
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
---
# GatewayでTLS終端を設定
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tls-gateway
namespace: gateway-system
spec:
gatewayClassName: nginx-gateway
listeners:
# HTTPSリスナー
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: example-tls
allowedRoutes:
namespaces:
from: All
# HTTPリスナー(HTTPSへリダイレクト)
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
---
# HTTPRoute(HTTPSのみ)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: secure-route
spec:
parentRefs:
- name: tls-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "secure.example.com"
rules:
- backendRefs:
- name: secure-service
port: 8080
複数ドメインのTLS設定
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: multi-domain-gateway
spec:
gatewayClassName: nginx-gateway
listeners:
# ドメイン1用のHTTPSリスナー
- name: https-domain1
protocol: HTTPS
port: 443
hostname: "domain1.example.com"
tls:
mode: Terminate
certificateRefs:
- name: domain1-tls
allowedRoutes:
namespaces:
from: All
# ドメイン2用のHTTPSリスナー
- name: https-domain2
protocol: HTTPS
port: 443
hostname: "domain2.example.com"
tls:
mode: Terminate
certificateRefs:
- name: domain2-tls
allowedRoutes:
namespaces:
from: All
TLSパススルー
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: passthrough-gateway
spec:
gatewayClassName: nginx-gateway
listeners:
- name: tls-passthrough
protocol: TLS
port: 443
tls:
mode: Passthrough
allowedRoutes:
kinds:
- kind: TLSRoute
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: secure-app-route
spec:
parentRefs:
- name: passthrough-gateway
hostnames:
- "secure-app.example.com"
rules:
- backendRefs:
- name: secure-app-service
port: 443
トラフィック分割とカナリアデプロイ
重み付けトラフィック分割
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: weighted-traffic
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
# 90%のトラフィックを安定版へ
- name: stable-service
port: 8080
weight: 90
# 10%のトラフィックをカナリア版へ
- name: canary-service
port: 8080
weight: 10
段階的カナリアデプロイ
# フェーズ1: 5%のトラフィックをカナリアへ
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-phase1
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: stable-v1
port: 8080
weight: 95
- name: canary-v2
port: 8080
weight: 5
---
# フェーズ2: 50%のトラフィックをカナリアへ
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-phase2
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: stable-v1
port: 8080
weight: 50
- name: canary-v2
port: 8080
weight: 50
---
# フェーズ3: 100%のトラフィックをカナリアへ
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-phase3
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: canary-v2
port: 8080
weight: 100
ヘッダーベースカナリア
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-canary
spec:
parentRefs:
- name: production-gateway
hostnames:
- "app.example.com"
rules:
# 特定のユーザーをカナリアへ
- matches:
- headers:
- name: X-User-Group
value: "beta-testers"
backendRefs:
- name: canary-service
port: 8080
# それ以外は安定版へ
- backendRefs:
- name: stable-service
port: 8080
リクエスト変換とリダイレクト
URLリライト
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: url-rewrite
spec:
parentRefs:
- name: production-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v1/users
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /api/users
backendRefs:
- name: user-service
port: 8080
リダイレクト
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: redirect-route
spec:
parentRefs:
- name: production-gateway
hostnames:
- "old.example.com"
rules:
# HTTPSへリダイレクト
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
# 新しいドメインへリダイレクト
- matches:
- path:
type: PathPrefix
value: /old-path
filters:
- type: RequestRedirect
requestRedirect:
hostname: "new.example.com"
path:
type: ReplacePrefixMatch
replacePrefixMatch: /new-path
statusCode: 301
ヘッダー操作
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-manipulation
spec:
parentRefs:
- name: production-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
# ヘッダーを追加
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Custom-Header
value: "custom-value"
- name: X-Request-ID
value: "${request.id}"
# ヘッダーを削除
remove:
- "X-Internal-Debug"
# ヘッダーを上書き
set:
- name: X-API-Version
value: "v1"
backendRefs:
- name: api-service
port: 8080
タイムアウトとリトライ
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: timeout-retry
spec:
parentRefs:
- name: production-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
timeouts:
# リクエストタイムアウト
request: 30s
# バックエンド接続タイムアウト
backendRequest: 10s
backendRefs:
- name: api-service
port: 8080
まとめ
Kubernetes Gateway APIは、従来のIngressを大幅に進化させた次世代のルーティングAPIです。主な利点は以下の通りです。
- ロールベース: インフラとアプリの責務分離
- 表現力: 複雑なルーティングロジックに対応
- ポータビリティ: ベンダー固有の設定が不要
- 拡張性: カスタムリソースで機能拡張可能
- 実用性: TLS、トラフィック分割、リクエスト変換など充実
Gateway APIは、Kubernetes 1.29でGA(Generally Available)となり、本番環境での使用が推奨されています。今後のKubernetesルーティングのスタンダードとして、積極的に採用を検討する価値があります。