Gateway API vs Ingress: Complete Comparison Guide for Kubernetes Networking
Introduction
Kubernetes networking has evolved significantly since the introduction of Ingress. While Ingress served as a good starting point for exposing HTTP applications, it had limitations that became apparent as Kubernetes usage grew more complex. Gateway API is the next-generation specification designed to address these limitations and provide a more expressive, extensible, and role-oriented networking interface.
Ingress: The First Generation
What is Ingress?
Ingress is a Kubernetes resource that manages external access to HTTP/HTTPS services in a cluster. It provides routing rules, SSL termination, and load balancing capabilities.
Key Components:
# Basic Ingress Example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
# TLS Configuration
tls:
- hosts:
- myapp.example.com
secretName: tls-secret
Limitations of Ingress:
- HTTP-Centric: Primarily designed for HTTP/HTTPS traffic
- Vendor Annotations: Heavy reliance on implementation-specific annotations
- Limited Expressiveness: Basic routing capabilities
- No Role Separation: Single resource for all concerns
- No Cross-Namespace Support: Can't reference services in other namespaces
- Limited Protocol Support: Poor support for TCP/UDP, gRPC, WebSocket
Gateway API: The Next Generation
What is Gateway API?
Gateway API is an open-source project managed by Kubernetes SIG-Network. It's designed as an evolution of Ingress, providing a more expressive, extensible, and role-oriented interface for service networking in Kubernetes.
Core Components:
- GatewayClass: Defines a class of Gateways that can be instantiated
- Gateway: Describes how traffic is translated to Services
- HTTPRoute/TCPRoute/UDPRoute/TLSRoute: Protocol-specific routing rules
- ReferenceGrant: Controls cross-namespace references
Key Features:
# Gateway API Architecture Example
┌─────────────────────────────────────┐
│ GatewayClass │
│ (e.g., "istio", "nginx", "contour")│
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Gateway │
│ (Infrastructure Provider managed) │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ HTTPRoute/TCPRoute │
│ (Application Developer) │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Services │
└─────────────────────────────────────┘
Direct Comparison: Gateway API vs Ingress
Feature Comparison Table:
| Feature | Ingress | Gateway API |
|---|---|---|
| Protocol Support | Primarily HTTP/HTTPS (limited TCP/UDP via annotations) | Multi-protocol native (HTTP, TCP, UDP, TLS, gRPC) |
| Role-Oriented Design | Single resource for all roles | Explicit separation: Infrastructure, Admin, App Developer |
| Cross-Namespace | Not supported | Native support with ReferenceGrant |
| Traffic Splitting | Basic via annotations | Native weighted routing |
| Header/Query Matching | Limited via annotations | Native rich matching capabilities |
| Request/Response Modifications | Basic via annotations | Native filters (headers, redirects, rewrites) |
| Backend Selection | Only Services | Services, ExternalNames, Direct Pod IPs |
| Extensibility | Limited to annotations | Rich extension points and custom resources |
| Portability | Low (vendor-specific annotations) | High (standard specification) |
Architecture Comparison:
# Ingress: Monolithic Approach
┌─────────────────────────────────┐
│ Ingress │
│ (Contains all configuration) │
├─────────────────────────────────┤
│ • Host/path routing │
│ • TLS termination │
│ • Load balancing │
│ • All vendor annotations │
└─────────────────────────────────┘
# Gateway API: Layered Approach
┌─────────────────────────────────┐
│ GatewayClass │
│ (Infrastructure capabilities) │
├─────────────────────────────────┤
│ Gateway │
│ (Listener configuration) │
├─────────────────────────────────┤
│ HTTPRoute │
│ (Application routing rules) │
└─────────────────────────────────┘
When to Use Each
Use Ingress When:
- Simple HTTP routing: Basic host/path-based routing
- Legacy applications: Applications using older Kubernetes versions
- Limited requirements: No need for advanced traffic management
- Quick setup: Need something working immediately
- Single team/role: Same team manages infrastructure and applications
Use Gateway API When:
- Multi-protocol needs: Need TCP, UDP, or gRPC support
- Role separation: Different teams manage infrastructure vs applications
- Multi-tenant environments: Need namespace isolation with cross-namespace routing
- Advanced traffic management: Need canary deployments, traffic splitting
- Future-proofing: Building new applications on modern standards
- Portability: Want to avoid vendor lock-in
Specific Scenarios:
# Scenario 1: Canary Deployment
# Ingress (using nginx annotations)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
backend:
service:
name: canary-service
port:
number: 80
# Gateway API (native support)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: canary-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: main-service
port: 80
weight: 90
- name: canary-service
port: 80
weight: 10
# Scenario 2: Cross-Namespace Routing
# Ingress: NOT POSSIBLE
# Services must be in same namespace as Ingress
# Gateway API: Supported with ReferenceGrant
# 1. Create ReferenceGrant in backend namespace
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-cross-namespace
namespace: backend-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: frontend-ns
to:
- group: ""
kind: Service
# 2. Create HTTPRoute referencing cross-namespace service
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: cross-ns-route
namespace: frontend-ns
spec:
parentRefs:
- name: my-gateway
rules:
- backendRefs:
- name: backend-service
namespace: backend-ns
port: 8080
Migration Guide: Ingress to Gateway API
Migration Strategy:
- Assessment: Evaluate current Ingress usage and requirements
- Pilot Project: Start with a non-critical application
- Parallel Run: Run both Ingress and Gateway API side-by-side
- Gradual Migration: Move applications incrementally
- Validation: Test thoroughly before full migration
- Cleanup: Remove old Ingress resources
Migration Example:
# Step 1: Current Ingress Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /web(/|$)(.*)
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Step 2: Equivalent Gateway API Configuration
# Gateway (infrastructure team)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
spec:
gatewayClassName: nginx
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: "app.example.com"
tls:
mode: Terminate
certificateRefs:
- name: app-tls
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
# HTTPRoute (application team)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: app-route
namespace: app-namespace
labels:
gateway-access: "true"
spec:
parentRefs:
- name: app-gateway
namespace: infrastructure-ns
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefix
replacePrefixMatch: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /web
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefix
replacePrefixMatch: /web
backendRefs:
- name: web-service
port: 80
Migration Tools:
# Using kwctl for Gateway API validation
# Install kwctl
curl -L https://github.com/kubewarden/kwctl/releases/download/v1.8.0/kwctl-linux-x86_64 -o kwctl
chmod +x kwctl
# Validate Gateway API resources
kwctl annotate -m gatekeeper-policy.yaml gateway.yaml
kwctl annotate -m gatekeeper-policy.yaml httproute.yaml
# Using kustomize for migration
# Create kustomize patch to transform Ingress to Gateway API
apiVersion: builtin
kind: PatchTransformer
metadata:
name: ingress-to-gateway
patch: |-
- op: replace
path: /apiVersion
value: gateway.networking.k8s.io/v1beta1
- op: replace
path: /kind
value: HTTPRoute
# Add additional transformations...
# Migration script example
#!/bin/bash
# migrate-ingress.sh
INGRESS_FILE=$1
NAMESPACE=$(yq eval '.metadata.namespace' $INGRESS_FILE)
GATEWAY_NAME="migrated-gateway"
echo "Migrating Ingress in namespace: $NAMESPACE"
# Extract host rules
HOSTS=$(yq eval '.spec.rules[].host' $INGRESS_FILE)
# Generate Gateway
cat > gateway.yaml <
Implementation Examples
Istio with Gateway API:
# Install Istio with Gateway API support
istioctl install --set profile=demo -y
# Create Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: istio-gateway
namespace: istio-system
spec:
gatewayClassName: istio
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: istio-cert
allowedRoutes:
namespaces:
from: All
# Create HTTPRoute with Istio features
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: bookinfo-route
spec:
parentRefs:
- name: istio-gateway
namespace: istio-system
hostnames:
- "bookinfo.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /productpage
- path:
type: PathPrefix
value: /static
- path:
type: PathExact
value: /login
- path:
type: PathExact
value: /logout
- path:
type: PathPrefix
value: /api/v1/products
backendRefs:
- name: productpage
port: 9080
- matches:
- headers:
- name: end-user
value: "jason"
- queryParams:
- name: test
value: "true"
backendRefs:
- name: reviews
port: 9080
weight: 90
- name: reviews-v2
port: 9080
weight: 10
NGINX Ingress Controller with Gateway API:
# Install NGINX Ingress Controller with Gateway API
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--set controller.ingressClassResource.name=nginx \
--set controller.ingressClassResource.controllerValue="k8s.io/ingress-nginx" \
--set controller.watchIngressWithoutClass=true \
--set controller.enableGatewayAPI=true
# Create GatewayClass
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: nginx.org/gateway-controller
# Create Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: nginx-gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
# Advanced routing with filters
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: advanced-route
spec:
parentRefs:
- name: nginx-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /shop
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Shop-Version
value: "v2"
set:
- name: X-User-ID
value: "12345"
remove:
- "X-Old-Header"
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Cache-Hit
value: "true"
- type: RequestRedirect
requestRedirect:
scheme: https
port: 8443
statusCode: 301
backendRefs:
- name: shop-service
port: 8080
TCP/UDP Routing Example:
# TCPRoute for database access
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: postgres-route
spec:
parentRefs:
- name: tcp-gateway
rules:
- backendRefs:
- name: postgres-primary
port: 5432
- name: postgres-replica
port: 5432
# UDPRoute for DNS service
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: UDPRoute
metadata:
name: dns-route
spec:
parentRefs:
- name: udp-gateway
rules:
- backendRefs:
- name: coredns
port: 53
# TLSRoute for passthrough TLS
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: tls-passthrough-route
spec:
parentRefs:
- name: tls-gateway
hostnames:
- "secure-api.example.com"
rules:
- backendRefs:
- name: secure-api-service
port: 8443
Best Practices
Gateway API Best Practices:
- Use Role Separation:
- Infrastructure team manages Gateway/GatewayClass
- Application teams manage HTTPRoutes
- Namespace Strategy:
- Place Gateway in infrastructure namespace
- Use namespace selectors for access control
- Use ReferenceGrant for cross-namespace access
- Security:
- Use TLS termination at Gateway when possible
- Implement network policies for Gateway
- Regularly rotate TLS certificates
- Monitoring:
- Monitor Gateway and Route status conditions
- Set up alerts for configuration errors
- Track traffic metrics per route
Performance Optimization:
# Optimize Gateway configuration
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: optimized-gateway
annotations:
# Implementation-specific optimizations
nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
# Connection limits
connectionLimits:
count: 10000
delay: 100ms
# Rate limiting
rateLimits:
standard:
requests: 100
unit: second
burst: 50
# Optimize HTTPRoute with caching
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: cached-route
annotations:
nginx.ingress.kubernetes.io/proxy-cache-path: "/tmp/nginx/cache"
nginx.ingress.kubernetes.io/proxy-cache-valid: "200 302 10m"
spec:
parentRefs:
- name: optimized-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /static
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: Cache-Control
value: "public, max-age=31536000"
backendRefs:
- name: static-service
port: 80
Future Outlook
Gateway API Roadmap:
- GAMMA Initiative: Gateway API for Mesh Management and Administration
- Service Mesh Integration: Better integration with service meshes
- Enhanced Observability: Standardized metrics and tracing
- Policy Framework: Built-in policy enforcement
- Wider Adoption: More implementations and ecosystem tools
Migration Timeline:
Recommended Migration Timeline:
Phase 1: Evaluation (Now)
├── Understand Gateway API concepts
├── Evaluate current Ingress limitations
├── Identify pilot project
└── Test with development clusters
Phase 2: Pilot (Q1-Q2 2024)
├── Implement Gateway API for pilot project
├── Train teams on new concepts
├── Develop migration patterns
└── Create monitoring and alerting
Phase 3: Gradual Migration (Q3-Q4 2024)
├── Migrate non-critical applications
├── Refine processes and tooling
├── Update CI/CD pipelines
└── Document lessons learned
Phase 4: Full Adoption (2025)
├── Migrate remaining applications
├── Deprecate Ingress usage
├── Optimize Gateway API configurations
└── Contribute to ecosystem
Key Recommendations:
- Start Learning Now: Gateway API is the future of Kubernetes networking
- Begin with Non-Critical Workloads: Gain experience safely
- Leverage Both Temporarily: Run Ingress and Gateway API in parallel
- Contribute to the Ecosystem: Help shape the future of the standard
- Stay Updated: Follow SIG-Network developments and releases
Comments
Post a Comment