Skip to content
Published on

Kubernetes Gateway API and GRPCRoute Complete Guide: From Service Mesh to Traffic Routing

Authors
  • Name
    Twitter

What Is Gateway API?

Kubernetes Gateway API is the next-generation networking API that goes beyond the limitations of the traditional Ingress resource. Through a role-based resource model (GatewayClass, Gateway, Route), it clearly separates the concerns of infrastructure operators and application developers.

Why Gateway API?

Problems with traditional Ingress:

  • All configuration concentrated in a single resource
  • Different annotations per implementation
  • No support for non-HTTP protocols like gRPC, TCP, UDP
  • No role separation

Gateway API addresses these issues:

# 1. GatewayClass managed by the infrastructure team
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
# 2. Gateway managed by the platform team
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 Deep Dive

GRPCRoute is a gRPC-specific routing resource included in Gateway API v1 (GA). Unlike HTTPRoute, it natively supports gRPC service/method-based matching.

Basic Structure

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

Header-Based Routing

You can route to different backends based on specific header values:

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

Traffic Splitting (Canary Deployment)

By specifying weights in GRPCRoute's backendRefs, you can distribute traffic by ratio:

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: Service Mesh Integration

GAMMA (Gateway API for Mesh Management and Administration) is an initiative to extend Gateway API into the service mesh domain.

The Core of GAMMA: Service as parentRef

In traditional Gateway API, the Route's parentRefs point to a Gateway. In GAMMA, the Service itself is specified as parentRef to control inter-service communication (East-West traffic):

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

Enabling GAMMA in Istio

# GAMMA support in Istio 1.22+
istioctl install --set profile=ambient

# Install Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml

Hands-On: gRPC Microservice Routing

Step 1: Deploy gRPC Services

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

Step 2: Configure the 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

Step 3: Define Routing Rules with 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

Step 4: Testing

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

# Verify canary deployment (call multiple times to check ratios)
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: Cross-Namespace Access Control

A ReferenceGrant is required to reference backends in other namespaces:

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

Monitoring and Debugging

Checking Gateway API Status

# Check Gateway status
kubectl get gateway -A
kubectl describe gateway grpc-gateway -n infra

# Check GRPCRoute status
kubectl get grpcroute -A
kubectl describe grpcroute user-grpc-route -n app

# Check Istio routing rules
istioctl proxy-config route deploy/istio-ingressgateway -n istio-system -o json

Prometheus Metrics

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

Production Checklist

Items to verify when adopting Gateway API in production:

  • Choose a GatewayClass implementation (Istio, Envoy Gateway, Cilium, etc.)
  • Automate TLS certificates (cert-manager integration)
  • Establish ReferenceGrant policies
  • Set up monitoring (Gateway status, routing metrics)
  • Configure rate limiting (BackendTrafficPolicy)
  • Define timeout and retry policies
  • Configure gRPC health checks
  • Plan a gradual migration

Review Quiz (5 Questions)

Q1. What are the three core resources for role separation in Gateway API?

GatewayClass, Gateway, Route (HTTPRoute/GRPCRoute, etc.)

Q2. What does the GRPCRoute's parentRefs point to in the GAMMA initiative?

Instead of a Gateway, the Service itself is specified as parentRef to control East-West (inter-service) traffic.

Q3. Which field is used to implement canary deployments in GRPCRoute?

The weight field in backendRefs is used to distribute traffic by ratio.

Q4. What resource is needed to reference a Service in another namespace as a backendRef?

A ReferenceGrant resource must be created in the target namespace.

Q5. Which field is used to match specific gRPC methods in GRPCRoute?

The rules.matches.method field, where you specify service and method.