Skip to content
Published on

Kubernetes Gateway APIとGRPCRoute完全ガイド:サービスメッシュからトラフィックルーティングまで

Authors
  • Name
    Twitter

Gateway APIとは?

Kubernetes Gateway APIは、従来のIngressリソースの限界を超えた次世代ネットワーキングAPIです。ロールベースのリソースモデル(GatewayClass、Gateway、Route)を通じて、インフラ運用者とアプリケーション開発者の関心事を明確に分離します。

なぜGateway APIなのか?

従来のIngressの問題点:

  • 単一リソースにすべての設定が集中
  • 実装ごとに異なるアノテーション
  • gRPC、TCP、UDPなどHTTP以外のプロトコル非対応
  • ロール分離が不可能

Gateway APIはこれらの問題を解決します:

# 1. インフラチームが管理するGatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
# 2. プラットフォームチームが管理するGateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: infra
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-cert
    - name: http
      protocol: HTTP
      port: 80

GRPCRoute詳細分析

GRPCRouteはGateway API v1(GA)に含まれるgRPC専用ルーティングリソースです。HTTPRouteとは異なり、gRPCのサービス/メソッドベースのマッチングをネイティブでサポートします。

基本構造

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-service-route
  namespace: app
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
      sectionName: grpc
  hostnames:
    - 'api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
      backendRefs:
        - name: user-service
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
      backendRefs:
        - name: user-write-service
          port: 50051

ヘッダーベースルーティング

特定のヘッダー値に基づいて異なるバックエンドにルーティングできます:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: ab-test-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
          headers:
            - name: x-experiment-group
              value: 'treatment-a'
      backendRefs:
        - name: recommendation-v2
          port: 50051
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
      backendRefs:
        - name: recommendation-v1
          port: 50051

トラフィックスプリッティング(カナリアデプロイメント)

GRPCRouteのbackendRefsにweightを指定すると、トラフィックを比率で分配できます:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: canary-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'order.v1.OrderService'
      backendRefs:
        - name: order-service-stable
          port: 50051
          weight: 90
        - name: order-service-canary
          port: 50051
          weight: 10

GAMMA:サービスメッシュ統合

GAMMA(Gateway API for Mesh Management and Administration)は、Gateway APIをサービスメッシュ領域に拡張するイニシアティブです。

GAMMAの核心:ServiceをparentRefとして指定

従来のGateway APIでは、RouteのparentRefsはGatewayを指します。GAMMAでは、Service自体をparentRefとして指定し、サービス間通信(East-Westトラフィック)を制御します:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: payment-mesh-route
spec:
  parentRefs:
    - group: ''
      kind: Service
      name: payment-service
      port: 50051
  rules:
    - matches:
        - method:
            service: 'payment.v1.PaymentService'
            method: 'ProcessPayment'
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: x-request-priority
                value: 'high'
      backendRefs:
        - name: payment-service
          port: 50051

IstioでGAMMAを有効化

# Istio 1.22以降でGAMMAをサポート
istioctl install --set profile=ambient

# Gateway API CRDのインストール
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml

実践ハンズオン:gRPCマイクロサービスルーティング

ステップ1:gRPCサービスのデプロイ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service-v1
  namespace: app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
      version: v1
  template:
    metadata:
      labels:
        app: user-service
        version: v1
    spec:
      containers:
        - name: user-service
          image: myregistry/user-service:v1.0
          ports:
            - containerPort: 50051
              name: grpc
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi
          livenessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 10
          readinessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: app
spec:
  selector:
    app: user-service
  ports:
    - name: grpc
      port: 50051
      targetPort: 50051
      appProtocol: kubernetes.io/grpc

ステップ2:Gatewayの設定

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: grpc-gateway
  namespace: infra
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc-tls
      protocol: HTTPS
      port: 443
      hostname: '*.api.example.com'
      tls:
        mode: Terminate
        certificateRefs:
          - name: api-tls-cert
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: 'true'
        kinds:
          - kind: GRPCRoute

ステップ3:GRPCRouteでルーティングルールを定義

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-grpc-route
  namespace: app
spec:
  parentRefs:
    - name: grpc-gateway
      namespace: infra
      sectionName: grpc-tls
  hostnames:
    - 'user.api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
        - method:
            service: 'user.v1.UserService'
            method: 'ListUsers'
      backendRefs:
        - name: user-service-reader
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'UpdateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'DeleteUser'
      backendRefs:
        - name: user-service-writer
          port: 50051

ステップ4:テスト

# grpcurlでテスト
grpcurl -d '{"user_id": "123"}' \
  -H "x-request-id: test-001" \
  user.api.example.com:443 \
  user.v1.UserService/GetUser

# カナリアデプロイメントの確認(複数回呼び出して比率を確認)
for i in $(seq 1 100); do
  grpcurl -d '{"user_id": "123"}' \
    user.api.example.com:443 \
    user.v1.UserService/GetUser 2>&1 | grep "server_version"
done | sort | uniq -c

ReferenceGrant:クロスNamespaceアクセス制御

他のNamespaceのバックエンドを参照するにはReferenceGrantが必要です:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-app-to-backend
  namespace: backend
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: GRPCRoute
      namespace: app
  to:
    - group: ''
      kind: Service

モニタリングとデバッグ

Gateway APIステータスの確認

# Gatewayステータスの確認
kubectl get gateway -A
kubectl describe gateway grpc-gateway -n infra

# GRPCRouteステータスの確認
kubectl get grpcroute -A
kubectl describe grpcroute user-grpc-route -n app

# Istioルーティングルールの確認
istioctl proxy-config route deploy/istio-ingressgateway -n istio-system -o json

Prometheusメトリクス

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: grpc-gateway-alerts
spec:
  groups:
    - name: grpc-gateway
      rules:
        - alert: GRPCHighErrorRate
          expr: |
            sum(rate(grpc_server_handled_total{grpc_code!="OK"}[5m])) by (grpc_service)
            /
            sum(rate(grpc_server_handled_total[5m])) by (grpc_service)
            > 0.05
          for: 5m
          labels:
            severity: warning

プロダクションチェックリスト

Gateway APIをプロダクションに導入する際の確認事項:

  • GatewayClass実装の選択(Istio、Envoy Gateway、Ciliumなど)
  • TLS証明書の自動化(cert-manager連携)
  • ReferenceGrantポリシーの策定
  • モニタリング(Gatewayステータス、ルーティングメトリクス)
  • レートリミット設定(BackendTrafficPolicy)
  • タイムアウトおよびリトライポリシー
  • gRPCヘルスチェック設定
  • 段階的マイグレーション計画

確認クイズ(5問)

Q1. Gateway APIでロール分離のための3つの核心リソースは?

GatewayClass、Gateway、Route(HTTPRoute/GRPCRouteなど)

Q2. GAMMAイニシアティブにおいてGRPCRouteのparentRefsが指すものは?

Gateway の代わりにService自体をparentRefとして指定し、East-West(サービス間)トラフィックを制御します。

Q3. GRPCRouteでカナリアデプロイメントを実装するにはどのフィールドを使いますか?

backendRefsのweightフィールドを使用してトラフィックの比率を分配します。

Q4. 他のNamespaceのServiceをbackendRefとして参照するにはどのリソースが必要ですか?

対象のNamespaceにReferenceGrantリソースを作成する必要があります。

Q5. GRPCRouteで特定のgRPCメソッドをマッチングするにはどのフィールドを使いますか?

rules.matches.methodフィールドにserviceとmethodを指定します。