Task: Migrate from OCP Route to GatewayAPI Route

Introduction

This guide provides detailed instructions for migrating from OpenShift Container Platform (OCP) Routes to Kubernetes Gateway API HTTPRoutes with Envoy Gateway. Each section covers a specific OCP Route feature and its equivalent configuration in Gateway API.

Prerequisites

  1. Configure EnvoyGatewayCtl
  2. Configure Gateway
  3. Basic understanding of Gateway API Routes

Basic HTTP Route

OCP Route Configuration

In OCP, a basic HTTP route is created using the Route resource:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  namespace: demo
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  port:
    targetPort: 8080
  1. The hostname for the route
  2. Backend service reference
  3. Target port on the backend service

Gateway API Configuration

In Gateway API, the equivalent configuration uses HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
      namespace: demo
  rules:
    - backendRefs:
        - name: example-service
          port: 8080
  1. Hostnames that this route accepts (equivalent to OCP Route's host)
  2. Reference to the Gateway listener
  3. Backend service and port

Route Timeouts

OCP Route Configuration

In OCP, timeouts are configured using annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/timeout: 30s
    haproxy.router.openshift.io/timeout-tunnel: 1h
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. General timeout for HTTP requests
  2. Timeout for tunnel connections (WebSocket, HTTP/2, etc.)

Gateway API Configuration

In Gateway API, timeouts are configured in the HTTPRoute rules:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - backendRefs:
        - name: example-service
          port: 8080
      timeouts:
        request: 30s
        backendRequest: 25s
  1. Request timeout configuration

For more details, see Request Timeouts.

NOTE

Gateway API does not have a separate timeout specifically for tunnel connections. The request timeout applies to all connection types.

HTTP Strict Transport Security (HSTS)

OCP Route Configuration

In OCP, HSTS is configured using the annotation on edge-terminated or re-encrypt routes:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  tls:
    termination: edge
  1. HSTS header configuration

Gateway API Configuration

In Gateway API, HSTS is configured using response header modification:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - filters:
        - type: ResponseHeaderModifier
          responseHeaderModifier:
            add:
              - name: Strict-Transport-Security
                value: max-age=31536000;includeSubDomains;preload
      backendRefs:
        - name: example-service
          port: 8080
  1. Add HSTS header to response

For more details, see HTTP Header Modification.

NOTE

Unlike OCP's requiredHSTSPolicies cluster-wide enforcement, Gateway API requires explicit configuration per route. There is no global HSTS policy enforcement mechanism in Gateway API.

OCP Route Configuration

In OCP, session affinity is configured using annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/balance: source
    haproxy.router.openshift.io/disable_cookies: "false"
    router.openshift.io/cookie_name: my-cookie
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. Load balancing algorithm
  2. Enable cookie-based session affinity
  3. Cookie name for session persistence

Gateway API Configuration

In Gateway API, session persistence is configured in the HTTPRoute rules:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - backendRefs:
        - name: example-service
          port: 8080
      sessionPersistence:
        type: Cookie
        sessionName: my-cookie
        cookieConfig:
          lifetimeType: Permanent
  1. Session persistence configuration
  2. Cookie lifetime type: Permanent (persists across browser sessions) or Session (expires when browser closes)

For more details, see Session Affinity/Sticky Sessions.

Path-Based Routing

OCP Route Configuration

In OCP, path-based routing uses the path field:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
spec:
  host: example.com
  path: /api
  to:
    kind: Service
    name: example-service
  1. Path prefix for matching requests

Gateway API Configuration

In Gateway API, path matching is configured in the HTTPRoute rules:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: example-service
          port: 8080
  1. Path matching configuration

Gateway API supports multiple match types:

  • PathPrefix: Matches the path prefix (equivalent to OCP's default behavior)
  • Exact: Matches the exact path
  • RegularExpression: Matches using regular expressions

For more details, see HTTPRoute Matches.

Header Modification

OCP Route Configuration

In OCP, header modification uses annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/response-set-header: X-Custom-Header:value
    haproxy.router.openshift.io/request-set-header: X-Request-Header:value
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. Set response headers
  2. Set request headers

Gateway API Configuration

In Gateway API, header modification is configured using filters:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: X-Request-Header
                value: value
        - type: ResponseHeaderModifier
          responseHeaderModifier:
            add:
              - name: X-Custom-Header
                value: value
      backendRefs:
        - name: example-service
          port: 8080
  1. Request header modification
  2. Response header modification

For more details, see HTTP Header Modification.

Connection Limits

OCP Route Configuration

In OCP, connection limits are configured using annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/pod-concurrent-connections: "100"
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. Maximum concurrent connections per backend pod

Gateway API Configuration

In Gateway API, connection limits are configured using ClientTrafficPolicy attached to the Gateway:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
  name: connection-limit-policy
  namespace: demo
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: demo-gateway
  connection:
    connectionLimit:
      value: 100
  1. Attach policy to Gateway
  2. Connection limit configuration

For more details, see Connection Limit.

NOTE

Unlike OCP's per-backend pod limit, Gateway API's connection limit is applied at the Gateway level and is distributed across Envoy proxy instances.

Rate Limiting

OCP Route Configuration

In OCP, rate limiting uses annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/rate-limit-connections: "true"
    haproxy.router.openshift.io/rate-limit-connections.concurrent-tcp: "10"
    haproxy.router.openshift.io/rate-limit-connections.rate-http: "100"
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. Rate limiting configuration

Gateway API Configuration

In Gateway API, rate limiting is configured using BackendTrafficPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: rate-limit-policy
  namespace: demo
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: example-route
  rateLimit:
    type: Local
    local:
      rules:
        - limit:
            requests: 100
            unit: Second
  1. Rate limiting configuration

For more details, see Rate Limiting.

NOTE

Gateway API rate limiting is more flexible than OCP Route annotations and supports both local and global rate limiting mechanisms.

IP Allowlist/Blocklist

OCP Route Configuration

In OCP, IP allowlisting uses annotations:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/ip_allowlist: 192.168.1.0/24 10.0.0.1
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  1. IP allowlist configuration

Gateway API Configuration

In Gateway API, IP filtering is implemented using SecurityPolicy with authorization rules:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: ip-filter-policy
  namespace: demo
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: example-route
  authorization:
    defaultAction: Deny
    rules:
      - action: Allow
        principal:
          clientCIDRs:
            - 192.168.1.0/24
            - 10.0.0.1/32
  1. Attach policy to HTTPRoute
  2. Authorization configuration with default deny
  3. IP allowlist using CIDR notation

For IP blocklist (denylist), set defaultAction: Allow and use action: Deny:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: ip-blocklist-policy
  namespace: demo
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      name: example-route
  authorization:
    defaultAction: Allow
    rules:
      - action: Deny
        principal:
          clientCIDRs:
            - 192.168.100.0/24
  1. Default action allows all traffic
  2. Deny traffic from specific IPs

For more details, see IP Allowlist/Denylist.

NOTE

Ensure you configure the client IP detection correctly using ClientTrafficPolicy if your Gateway is behind a load balancer or proxy.

URL Rewrite

OCP Route Configuration

In OCP, URL rewriting uses the annotation:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
  annotations:
    haproxy.router.openshift.io/rewrite-target: /new-path
spec:
  host: example.com
  path: /old-path
  to:
    kind: Service
    name: example-service
  1. Rewrite target path

Gateway API Configuration

In Gateway API, URL rewriting is configured using filters:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  hostnames:
    - example.com
  parentRefs:
    - name: demo-gateway
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /old-path
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /new-path
      backendRefs:
        - name: example-service
          port: 8080
  1. URL rewrite filter

For more details, see URL Rewrite.

Cross-Namespace Route Admission

OCP Route Configuration

In OCP, the route admission policy controls whether routes in different namespaces can claim the same hostname. This is configured at the cluster level through the Ingress Operator.

Gateway API Configuration

In Gateway API, cross-namespace access is controlled at the Gateway listener level:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: gateway-ns
spec:
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: All  # Allow routes from all namespaces
  1. Configure which namespaces can attach routes

Options for allowedRoutes.namespaces.from:

  • Same: Only routes in the same namespace as the Gateway
  • All: Routes from any namespace
  • Selector: Routes from namespaces matching a label selector

For more details, see Cross-Namespace Routing.

NOTE

Unlike OCP's cluster-wide admission policy, Gateway API controls this at the individual Gateway listener level, providing more granular control.

Default TLS Certificate for Ingress

OCP Route Configuration

In OCP, routes without TLS configuration can use a default certificate configured at the Ingress Controller level.

Gateway API Configuration

In Gateway API, configure a default TLS certificate on the Gateway listener:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: demo
spec:
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: default-tls-cert
  1. Default TLS certificate for the listener

Any HTTPRoute attached to this listener without specific TLS configuration will use this default certificate.

TLS Re-encrypt with Custom CA

OCP Route Configuration

In OCP, re-encrypt routes terminate TLS at the router and re-encrypt to the backend with validation:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  tls:
    termination: reencrypt
    destinationCACertificate: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
  1. Re-encrypt termination mode
  2. CA certificate for validating backend

Gateway API Configuration

In Gateway API, backend TLS validation is configured using BackendTLSPolicy:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: demo
spec:
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: frontend-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
  name: backend-tls-policy
  namespace: demo
spec:
  targetRefs:
    - group: ""
      kind: Service
      name: example-service
  validation:
    caCertificateRefs:
      - name: backend-ca-cert
        kind: ConfigMap
    hostname: backend.example.com
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  parentRefs:
    - name: demo-gateway
  hostnames:
    - example.com
  rules:
    - backendRefs:
        - name: example-service
          port: 8443
  1. Terminate TLS at the Gateway
  2. Apply policy to the backend Service
  3. Backend TLS validation configuration

For more details, see Backend TLS.

NOTE

The CA certificate must be stored in a ConfigMap, not a Secret.

Edge Termination with Custom Certificate

OCP Route Configuration

In OCP, edge termination uses the route's TLS configuration:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  tls:
    termination: edge
    certificate: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      ...
      -----END PRIVATE KEY-----
  1. Edge termination mode
  2. TLS certificate
  3. TLS private key

Gateway API Configuration

In Gateway API, TLS termination is configured on the Gateway listener:

apiVersion: v1
kind: Secret
metadata:
  name: example-tls
  namespace: demo
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-cert>
  tls.key: <base64-encoded-key>
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: demo
spec:
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: demo
spec:
  parentRefs:
    - name: demo-gateway
      sectionName: https
  hostnames:
    - example.com
  rules:
    - backendRefs:
        - name: example-service
          port: 8080
  1. TLS secret type
  2. HTTPS protocol
  3. Terminate TLS mode
  4. Reference to TLS secret

TLS Passthrough

OCP Route Configuration

In OCP, passthrough routes do not terminate TLS:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: example-route
spec:
  host: example.com
  to:
    kind: Service
    name: example-service
  tls:
    termination: passthrough
  1. Passthrough termination mode

Gateway API Configuration

In Gateway API, TLS passthrough uses TLSRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: demo
spec:
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: tls-passthrough
      protocol: TLS
      port: 443
      tls:
        mode: Passthrough
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: example-route
  namespace: demo
spec:
  parentRefs:
    - name: demo-gateway
      sectionName: tls-passthrough
  hostnames:
    - example.com
  rules:
    - backendRefs:
        - name: example-service
          port: 8443
  1. TLS protocol
  2. Passthrough mode
  3. SNI hostname for routing

For more details, see TLS Passthrough and TLSRoute specification.

NOTE

TLSRoute uses SNI (Server Name Indication) for routing decisions without terminating TLS. This means:

  • No access to HTTP headers or request content for routing decisions
  • No L7 filters (header modification, URL rewrite, etc.) can be applied
  • Routing is purely based on the SNI hostname

Feature Comparison Summary

FeatureOCP RouteGateway APINotes
Basic HTTP RoutingRoute specHTTPRouteDirect mapping
Path-based Routing.spec.path.spec.rules[].matches[].pathGateway API offers more match types
TimeoutsAnnotationsHTTPRoute .spec.rules[].timeoutsGateway API has structured timeout configuration
HSTSAnnotationResponseHeaderModifier filterNo global enforcement in Gateway API
Session AffinityAnnotationsHTTPRoute .spec.rules[].sessionPersistenceGateway API has native support
Header ModificationAnnotationsRequestHeaderModifier/ResponseHeaderModifier filtersGateway API has structured filter configuration
Connection LimitsAnnotationClientTrafficPolicyApplied at Gateway level, distributed across proxies
Rate LimitingAnnotationsBackendTrafficPolicyMore flexible in Gateway API
IP Allowlist/BlocklistAnnotationSecurityPolicy with authorizationNative support via clientCIDRs
URL RewriteAnnotationURLRewrite filterGateway API has structured rewrite configuration
Cross-NamespaceCluster-level policyGateway .spec.listeners[].allowedRoutesGateway API has per-listener control
Default TLS CertController-levelGateway listener TLSPer-listener configuration
TLS Re-encrypt.spec.tls.termination: reencryptBackendTLSPolicyRequires separate policy resource
TLS Edge.spec.tls.termination: edgeGateway listener TLS with HTTPSCertificate in Secret
TLS Passthrough.spec.tls.termination: passthroughTLSRoute with Passthrough modeUses TLSRoute instead of HTTPRoute

Migration Strategy

When migrating from OCP Routes to Gateway API:

  1. Start with a Gateway: Create a Gateway resource with appropriate listeners for your use case

    • Deploy the Gateway in the same namespace or a dedicated gateway namespace
    • Configure listeners for all protocols you need (HTTP, HTTPS, TLS, TCP, UDP)
    • Ensure the Gateway service is created and has an accessible endpoint
  2. Convert Routes to HTTPRoutes: Migrate each OCP Route to an HTTPRoute, starting with simple routes

    • Begin with non-production or low-traffic routes to minimize risk
    • Verify hostname and path matching configurations
    • Test basic connectivity before adding advanced features
  3. Apply Policies: For features that require policies (BackendTrafficPolicy, SecurityPolicy, ClientTrafficPolicy), create and attach them after the basic route is working

    • Add one policy at a time and validate functionality
    • Monitor for any unexpected behavior or performance impact
  4. Test Incrementally: Validate each migration step before proceeding to the next route

    • Monitoring: Check Gateway and Route status conditions for any errors
    • Functional Testing: Verify all routes work as expected with curl or automated tests
    • Performance Testing: Compare response times and throughput with OCP Routes
    • Validation Checks:
      • Verify TLS certificates are correctly applied
      • Test session affinity and load balancing behavior
      • Validate rate limiting and security policies
      • Check header modification and URL rewrites
  5. Update DNS: Once validated, update DNS entries to point to the new Gateway service

    • Dual-Running Period (recommended): Point a subset of traffic to the new Gateway while keeping OCP Routes active for rollback capability
    • Gradually shift traffic using weighted DNS or canary deployments
    • Monitor error rates, latency, and application metrics during cutover
  6. Rollback Procedures: If issues are discovered after migration

    • Revert DNS to point back to OCP Routes
    • Keep OCP Routes active for at least 24-48 hours after DNS cutover
    • Document any configuration differences that caused issues
    • Have a communication plan for stakeholders if rollback is needed