# 1. GatewayClass — Defined by infrastructure admin
# Determines which controller manages Gateways of this class
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata: name: production-gateway
spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller description: "Production traffic gateway managed by Envoy Gateway"
---
# 2. Gateway — Defined by cluster operator
# Provisions the actual load balancer instance
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: main-gateway namespace: gateway-infra
spec: gatewayClassName: production-gateway listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: wildcard-tls namespace: cert-manager allowedRoutes: namespaces: from: Selector selector: matchLabels: gateway-access: "true" - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same
# 1. GatewayClass — Defined by infrastructure admin
# Determines which controller manages Gateways of this class
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata: name: production-gateway
spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller description: "Production traffic gateway managed by Envoy Gateway"
---
# 2. Gateway — Defined by cluster operator
# Provisions the actual load balancer instance
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: main-gateway namespace: gateway-infra
spec: gatewayClassName: production-gateway listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: wildcard-tls namespace: cert-manager allowedRoutes: namespaces: from: Selector selector: matchLabels: gateway-access: "true" - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same
# 1. GatewayClass — Defined by infrastructure admin
# Determines which controller manages Gateways of this class
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata: name: production-gateway
spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller description: "Production traffic gateway managed by Envoy Gateway"
---
# 2. Gateway — Defined by cluster operator
# Provisions the actual load balancer instance
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: main-gateway namespace: gateway-infra
spec: gatewayClassName: production-gateway listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: wildcard-tls namespace: cert-manager allowedRoutes: namespaces: from: Selector selector: matchLabels: gateway-access: "true" - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same
# 3. HTTPRoute — Defined by application developer
# Routing rules to their own services
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: name: api-routes namespace: app-production
spec: parentRefs: - name: main-gateway namespace: gateway-infra sectionName: https hostnames: - "api.example.com" rules: # /api/v1/users -> user--weight: 500;">service - matches: - path: type: PathPrefix value: /api/v1/users backendRefs: - name: user--weight: 500;">service port: 8080 weight: 100 # /api/v1/courses -> course--weight: 500;">service (canary deployment) - matches: - path: type: PathPrefix value: /api/v1/courses backendRefs: - name: course--weight: 500;">service port: 8080 weight: 90 - name: course--weight: 500;">service-canary port: 8080 weight: 10 # Header-based routing - matches: - path: type: PathPrefix value: /api/v1/ headers: - name: X-Environment value: staging backendRefs: - name: staging--weight: 500;">service port: 8080
# 3. HTTPRoute — Defined by application developer
# Routing rules to their own services
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: name: api-routes namespace: app-production
spec: parentRefs: - name: main-gateway namespace: gateway-infra sectionName: https hostnames: - "api.example.com" rules: # /api/v1/users -> user--weight: 500;">service - matches: - path: type: PathPrefix value: /api/v1/users backendRefs: - name: user--weight: 500;">service port: 8080 weight: 100 # /api/v1/courses -> course--weight: 500;">service (canary deployment) - matches: - path: type: PathPrefix value: /api/v1/courses backendRefs: - name: course--weight: 500;">service port: 8080 weight: 90 - name: course--weight: 500;">service-canary port: 8080 weight: 10 # Header-based routing - matches: - path: type: PathPrefix value: /api/v1/ headers: - name: X-Environment value: staging backendRefs: - name: staging--weight: 500;">service port: 8080
# 3. HTTPRoute — Defined by application developer
# Routing rules to their own services
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: name: api-routes namespace: app-production
spec: parentRefs: - name: main-gateway namespace: gateway-infra sectionName: https hostnames: - "api.example.com" rules: # /api/v1/users -> user--weight: 500;">service - matches: - path: type: PathPrefix value: /api/v1/users backendRefs: - name: user--weight: 500;">service port: 8080 weight: 100 # /api/v1/courses -> course--weight: 500;">service (canary deployment) - matches: - path: type: PathPrefix value: /api/v1/courses backendRefs: - name: course--weight: 500;">service port: 8080 weight: 90 - name: course--weight: 500;">service-canary port: 8080 weight: 10 # Header-based routing - matches: - path: type: PathPrefix value: /api/v1/ headers: - name: X-Environment value: staging backendRefs: - name: staging--weight: 500;">service port: 8080
# BackendTLSPolicy — Gateway to backend TLS configuration
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata: name: backend-tls namespace: app-production
spec: targetRefs: - group: "" kind: Service name: secure-backend validation: caCertificateRefs: - name: backend-ca-cert group: "" kind: ConfigMap hostname: secure-backend.app-production.svc.cluster.local
# BackendTLSPolicy — Gateway to backend TLS configuration
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata: name: backend-tls namespace: app-production
spec: targetRefs: - group: "" kind: Service name: secure-backend validation: caCertificateRefs: - name: backend-ca-cert group: "" kind: ConfigMap hostname: secure-backend.app-production.svc.cluster.local
# BackendTLSPolicy — Gateway to backend TLS configuration
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata: name: backend-tls namespace: app-production
spec: targetRefs: - group: "" kind: Service name: secure-backend validation: caCertificateRefs: - name: backend-ca-cert group: "" kind: ConfigMap hostname: secure-backend.app-production.svc.cluster.local
# Install ingress2gateway (Go 1.22+)
go -weight: 500;">install github.com/kubernetes-sigs/[email protected] # Or download release binary
-weight: 500;">curl -LO https://github.com/kubernetes-sigs/ingress2gateway/releases/download/v1.0.0/ingress2gateway-linux-amd64
chmod +x ingress2gateway-linux-amd64
-weight: 600;">sudo mv ingress2gateway-linux-amd64 /usr/local/bin/ingress2gateway # Convert all Ingress resources to Gateway API (dry-run)
ingress2gateway print --providers ingress-nginx # Specific namespace
ingress2gateway print --providers ingress-nginx --namespace production # Save to file
ingress2gateway print --providers ingress-nginx --namespace production > gateway-resources.yaml # Vendor-specific emitter (Envoy Gateway extensions)
ingress2gateway print --providers ingress-nginx --emitter envoy-gateway > envoy-gateway-resources.yaml
# Install ingress2gateway (Go 1.22+)
go -weight: 500;">install github.com/kubernetes-sigs/[email protected] # Or download release binary
-weight: 500;">curl -LO https://github.com/kubernetes-sigs/ingress2gateway/releases/download/v1.0.0/ingress2gateway-linux-amd64
chmod +x ingress2gateway-linux-amd64
-weight: 600;">sudo mv ingress2gateway-linux-amd64 /usr/local/bin/ingress2gateway # Convert all Ingress resources to Gateway API (dry-run)
ingress2gateway print --providers ingress-nginx # Specific namespace
ingress2gateway print --providers ingress-nginx --namespace production # Save to file
ingress2gateway print --providers ingress-nginx --namespace production > gateway-resources.yaml # Vendor-specific emitter (Envoy Gateway extensions)
ingress2gateway print --providers ingress-nginx --emitter envoy-gateway > envoy-gateway-resources.yaml
# Install ingress2gateway (Go 1.22+)
go -weight: 500;">install github.com/kubernetes-sigs/[email protected] # Or download release binary
-weight: 500;">curl -LO https://github.com/kubernetes-sigs/ingress2gateway/releases/download/v1.0.0/ingress2gateway-linux-amd64
chmod +x ingress2gateway-linux-amd64
-weight: 600;">sudo mv ingress2gateway-linux-amd64 /usr/local/bin/ingress2gateway # Convert all Ingress resources to Gateway API (dry-run)
ingress2gateway print --providers ingress-nginx # Specific namespace
ingress2gateway print --providers ingress-nginx --namespace production # Save to file
ingress2gateway print --providers ingress-nginx --namespace production > gateway-resources.yaml # Vendor-specific emitter (Envoy Gateway extensions)
ingress2gateway print --providers ingress-nginx --emitter envoy-gateway > envoy-gateway-resources.yaml
# Install Gateway API CRDs (v1.4.0)
# WARNING: v1.5.x causes istiod crash with Istio 1.28/1.29
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml # Verify CRD installation
-weight: 500;">kubectl get crd | grep gateway # For experimental channel (TCPRoute, UDPRoute)
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental--weight: 500;">install.yaml
# Install Gateway API CRDs (v1.4.0)
# WARNING: v1.5.x causes istiod crash with Istio 1.28/1.29
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml # Verify CRD installation
-weight: 500;">kubectl get crd | grep gateway # For experimental channel (TCPRoute, UDPRoute)
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental--weight: 500;">install.yaml
# Install Gateway API CRDs (v1.4.0)
# WARNING: v1.5.x causes istiod crash with Istio 1.28/1.29
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml # Verify CRD installation
-weight: 500;">kubectl get crd | grep gateway # For experimental channel (TCPRoute, UDPRoute)
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental--weight: 500;">install.yaml
# Inventory all Ingress resources
-weight: 500;">kubectl get ingress --all-namespaces -o wide # Analyze annotation usage patterns
-weight: 500;">kubectl get ingress --all-namespaces -o json | \ jq -r '.items[].metadata.annotations // {} | keys[]' | \ sort | uniq -c | sort -rn # Preview conversion
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | tee migration-preview.yaml # Check for unsupported annotations
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | grep "WARNING"
# Inventory all Ingress resources
-weight: 500;">kubectl get ingress --all-namespaces -o wide # Analyze annotation usage patterns
-weight: 500;">kubectl get ingress --all-namespaces -o json | \ jq -r '.items[].metadata.annotations // {} | keys[]' | \ sort | uniq -c | sort -rn # Preview conversion
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | tee migration-preview.yaml # Check for unsupported annotations
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | grep "WARNING"
# Inventory all Ingress resources
-weight: 500;">kubectl get ingress --all-namespaces -o wide # Analyze annotation usage patterns
-weight: 500;">kubectl get ingress --all-namespaces -o json | \ jq -r '.items[].metadata.annotations // {} | keys[]' | \ sort | uniq -c | sort -rn # Preview conversion
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | tee migration-preview.yaml # Check for unsupported annotations
ingress2gateway print --providers ingress-nginx --all-namespaces 2>&1 | grep "WARNING"
# Install Envoy Gateway (Helm)
helm -weight: 500;">install envoy-gateway oci://-weight: 500;">docker.io/envoyproxy/gateway-helm \ --version v1.3.0 \ --namespace envoy-gateway-system \ --create-namespace # Verify GatewayClass
-weight: 500;">kubectl get gatewayclass
# Install Envoy Gateway (Helm)
helm -weight: 500;">install envoy-gateway oci://-weight: 500;">docker.io/envoyproxy/gateway-helm \ --version v1.3.0 \ --namespace envoy-gateway-system \ --create-namespace # Verify GatewayClass
-weight: 500;">kubectl get gatewayclass
# Install Envoy Gateway (Helm)
helm -weight: 500;">install envoy-gateway oci://-weight: 500;">docker.io/envoyproxy/gateway-helm \ --version v1.3.0 \ --namespace envoy-gateway-system \ --create-namespace # Verify GatewayClass
-weight: 500;">kubectl get gatewayclass
# Gateway + ReferenceGrant for parallel deployment
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: migration-gateway namespace: gateway-infra
spec: gatewayClassName: eg listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: api-tls-cert allowedRoutes: namespaces: from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-gateway-refs namespace: app-production
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service
# Gateway + ReferenceGrant for parallel deployment
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: migration-gateway namespace: gateway-infra
spec: gatewayClassName: eg listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: api-tls-cert allowedRoutes: namespaces: from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-gateway-refs namespace: app-production
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service
# Gateway + ReferenceGrant for parallel deployment
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: name: migration-gateway namespace: gateway-infra
spec: gatewayClassName: eg listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret name: api-tls-cert allowedRoutes: namespaces: from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-gateway-refs namespace: app-production
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service
# 1. Deploy Gateway API resources (parallel with existing Ingress)
-weight: 500;">kubectl apply -f gateway-resources.yaml # 2. Get external IP assigned to Gateway
-weight: 500;">kubectl get gateway migration-gateway -n gateway-infra -o jsonpath='{.-weight: 500;">status.addresses[0].value}' # 3. Gradually shift DNS weights
# ingress-nginx LB: 90 -> 50 -> 10 -> 0
# gateway API LB: 10 -> 50 -> 90 -> 100 # 4. Verify traffic
-weight: 500;">curl -H "Host: api.example.com" https://<GATEWAY_IP>/api/v1/health # 5. Cleanup after full transition
-weight: 500;">kubectl delete ingress --all -n app-production
helm uninstall ingress-nginx -n ingress-nginx
# 1. Deploy Gateway API resources (parallel with existing Ingress)
-weight: 500;">kubectl apply -f gateway-resources.yaml # 2. Get external IP assigned to Gateway
-weight: 500;">kubectl get gateway migration-gateway -n gateway-infra -o jsonpath='{.-weight: 500;">status.addresses[0].value}' # 3. Gradually shift DNS weights
# ingress-nginx LB: 90 -> 50 -> 10 -> 0
# gateway API LB: 10 -> 50 -> 90 -> 100 # 4. Verify traffic
-weight: 500;">curl -H "Host: api.example.com" https://<GATEWAY_IP>/api/v1/health # 5. Cleanup after full transition
-weight: 500;">kubectl delete ingress --all -n app-production
helm uninstall ingress-nginx -n ingress-nginx
# 1. Deploy Gateway API resources (parallel with existing Ingress)
-weight: 500;">kubectl apply -f gateway-resources.yaml # 2. Get external IP assigned to Gateway
-weight: 500;">kubectl get gateway migration-gateway -n gateway-infra -o jsonpath='{.-weight: 500;">status.addresses[0].value}' # 3. Gradually shift DNS weights
# ingress-nginx LB: 90 -> 50 -> 10 -> 0
# gateway API LB: 10 -> 50 -> 90 -> 100 # 4. Verify traffic
-weight: 500;">curl -H "Host: api.example.com" https://<GATEWAY_IP>/api/v1/health # 5. Cleanup after full transition
-weight: 500;">kubectl delete ingress --all -n app-production
helm uninstall ingress-nginx -n ingress-nginx
# Symptom: istiod CrashLoopBackOff
-weight: 500;">kubectl logs -n istio-system deployment/istiod | grep "gateway" # Fix: Downgrade CRDs
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml
-weight: 500;">kubectl rollout -weight: 500;">restart deployment/istiod -n istio-system
# Symptom: istiod CrashLoopBackOff
-weight: 500;">kubectl logs -n istio-system deployment/istiod | grep "gateway" # Fix: Downgrade CRDs
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml
-weight: 500;">kubectl rollout -weight: 500;">restart deployment/istiod -n istio-system
# Symptom: istiod CrashLoopBackOff
-weight: 500;">kubectl logs -n istio-system deployment/istiod | grep "gateway" # Fix: Downgrade CRDs
-weight: 500;">kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard--weight: 500;">install.yaml
-weight: 500;">kubectl rollout -weight: 500;">restart deployment/istiod -n istio-system
# Extract unsupported annotations
ingress2gateway print --providers ingress-nginx 2>&1 | \ grep "WARNING.*annotation" | \ sed 's/.*annotation "\(.*\)" is not.*/\1/' | \ sort -u > unsupported-annotations.txt # Common manual mappings:
# limit-rps -> Envoy Gateway RateLimitPolicy
# auth-url -> Envoy Gateway SecurityPolicy (ExtAuth)
# modsecurity-* -> Separate WAF solution required
# Extract unsupported annotations
ingress2gateway print --providers ingress-nginx 2>&1 | \ grep "WARNING.*annotation" | \ sed 's/.*annotation "\(.*\)" is not.*/\1/' | \ sort -u > unsupported-annotations.txt # Common manual mappings:
# limit-rps -> Envoy Gateway RateLimitPolicy
# auth-url -> Envoy Gateway SecurityPolicy (ExtAuth)
# modsecurity-* -> Separate WAF solution required
# Extract unsupported annotations
ingress2gateway print --providers ingress-nginx 2>&1 | \ grep "WARNING.*annotation" | \ sed 's/.*annotation "\(.*\)" is not.*/\1/' | \ sort -u > unsupported-annotations.txt # Common manual mappings:
# limit-rps -> Envoy Gateway RateLimitPolicy
# auth-url -> Envoy Gateway SecurityPolicy (ExtAuth)
# modsecurity-* -> Separate WAF solution required
# Fix: Create ReferenceGrant in the target namespace
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-from-app-ns namespace: shared-services
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service
# Fix: Create ReferenceGrant in the target namespace
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-from-app-ns namespace: shared-services
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service
# Fix: Create ReferenceGrant in the target namespace
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata: name: allow-from-app-ns namespace: shared-services
spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: app-production to: - group: "" kind: Service - Run -weight: 500;">kubectl get ingress --all-namespaces to inventory your current Ingress resources
- Run ingress2gateway print to assess automatic conversion coverage and identify manual mapping needs
- Deploy a Gateway API controller in staging and validate converted resources