This is a cache of https://docs.okd.io/4.19/networking/ingress_load_balancing/configuring_ingress_cluster_traffic/ingress-gateway-api.html. It is a snapshot of the page at 2025-08-12T20:41:42.898+0000.
Gateway API with OpenShift Container Platform networking - <strong>ingress</strong> and load balancing | Networking | OKD 4.19
×

OKD provides additional ways of configuring network traffic by using Gateway API with the ingress Operator.

Gateway API does not support user-defined networks (UDN).

Overview of Gateway API

Gateway API is an open source, community-managed, Kubernetes networking mechanism. It focuses on routing within the transport layer, L4, and the application layer, L7, for clusters. A variety of vendors offer many implementations of Gateway API.

The project is an effort to provide a standardized ecosystem by using a portable API with broad community support. By integrating Gateway API functionality into the ingress Operator, it enables a networking solution that aligns with existing community and upstream development efforts.

Gateway API extends the functionality of the ingress Operator to handle more granular cluster traffic and routing configurations. With these capabilities, you can create instances of Gateway APIs custom resource definitions (CRDs). For OKD clusters, the ingress Operator creates the following resources:

Gateway

This resource describes how traffic can be translated to services within the cluster. For example, a specific load balancer configuration.

GatewayClass

This resource defines a set of Gateway objects that share a common configuration and behavior. For example, two separate GatewayClass objects might be created to distinguish a set of Gateway resources used for public or private applications.

HTTPRoute

This resource specifies the routing behavior of HTTP requests from a Gateway to a service, and is especially useful for multiplexing HTTP or terminated HTTPS connections.

GRPCRoute

This resource specifies the routing behavior of gRPC requests.

ReferenceGrant

This resource enables cross-namespace references. For example, it enables routes to forward traffic to backends that are in a different namespace.

In OKD, the implementation of Gateway API is based on gateway.networking.k8s.io/v1, and all fields in this version are supported.

Benefits of Gateway API

Gateway API provides the following benefits:

  • Portability: While OKD uses HAProxy to improve ingress performance, Gateway API does not rely on vendor-specific annotations to provide certain behavior. To get comparable performance as HAProxy, the Gateway objects need to be horizontally scaled or their associated nodes need to be vertically scaled.

  • Separation of concerns: Gateway API uses a role-based approach to its resources, and more neatly fits into how a large organization structures its responsibilities and teams. Platform engineers might focus on GatewayClass resources, cluster admins might focus on configuring Gateway resources, and application developers might focus on routing their services with HTTPRoute resources.

  • Extensibility: Additional functionality is developed as a standardized CRD.

Limitations of Gateway API

Gateway API has the following limitations:

  • Version incompatibilities: Gateway API ecosystem changes rapidly, and some implementations do not work with others because their featureset is based on differing versions of Gateway API.

  • Resource overhead: While more flexible, Gateway API uses multiple resource types to achieve an outcome. For smaller applications, the simplicity of traditional ingress might be a better fit.

Gateway API implementation for OKD

The ingress Operator manages the lifecycle of Gateway API CRDs in a way that enables other vendor implementations to make use of CRDs defined in an OKD cluster.

In some situations, Gateway API provides one or more fields that a vendor implementation does not support, but that implementation is otherwise compatible in schema with the rest of the fields. These "dead fields" can result in disrupted ingress workloads, improperly provisioned applications and services, and security related issues. Because OKD uses a specific version of Gateway API CRDs, any use of third-party implementations of Gateway API must conform to the OKD implementation to ensure that all fields work as expected.

Any CRDs created within an OKD 4.19 cluster are compatibly versioned and maintained by the ingress Operator. If CRDs are already present but were not previously managed by the ingress Operator, the ingress Operator checks whether these configurations are compatible with Gateway API version supported by OKD, and creates an admin-gate that requires your acknowledgment of CRD succession.

If you are updating your cluster from a previous OKD version that contains Gateway API CRDs change those resources so that they exactly match the version supported by OKD. Otherwise, you cannot update your cluster because those CRDs were not managed by OKD, and could contain functionality that is unsupported by Red Hat.

Getting started with Gateway API for the ingress Operator

When you create a GatewayClass as shown in the first step, it configures Gateway API for use on your cluster.

Procedure
  1. Create a GatewayClass object:

    1. Create a YAML file, openshift-default.yaml, that contains the following information:

      Example GatewayClass CR
      apiVersion: gateway.networking.k8s.io/v1
      kind: GatewayClass
      metadata:
        name: openshift-default
      spec:
        controllerName: openshift.io/gateway-controller/v1 (1)
      1 The controller name.

      The controller name must be exactly as shown for the ingress Operator to manage it. If you set this field to anything else, the ingress Operator ignores the GatewayClass object and all associated Gateway, GRPCRoute, and HTTPRoute objects. The controller name is tied to the implementation of Gateway API in OKD, and openshift.io/gateway-controller/v1 is the only controller name allowed.

    2. Run the following command to create the GatewayClass resource:

      $ oc create -f openshift-default.yaml
      Example output
      gatewayclass.gateway.networking.k8s.io/openshift-default created

      During the creation of the GatewayClass resource, the ingress Operator installs a lightweight version of Red Hat OpenShift Service Mesh, an Istio custom resource, and a new deployment in the openshift-ingress namespace.

    3. Optional: Verify that the new deployment, istiod-openshift-gateway is ready and available:

      $ oc get deployment -n openshift-ingress
      Example output
      NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
      istiod-openshift-gateway   1/1     1            1           55s
      router-default             2/2     2            2           6h4m
  2. Create a secret by running the following command:

    $ oc -n openshift-ingress create secret tls gwapi-wildcard --cert=wildcard.crt --key=wildcard.key
  3. Get the domain of the ingress Operator by running the following command:

    $ DOMAIN=$(oc get ingresses.config/cluster -o jsonpath={.spec.domain})
  4. Create a Gateway object:

    1. Create a YAML file, example-gateway.yaml, that contains the following information:

      Example Gateway CR
      apiVersion: gateway.networking.k8s.io/v1
      kind: Gateway
      metadata:
        name: example-gateway
        namespace: openshift-ingress (1)
      spec:
        gatewayClassName: openshift-default (2)
        listeners:
        - name: https (3)
          hostname: "*.gwapi.${DOMAIN}" (4)
          port: 443
          protocol: HTTPS
          tls:
            mode: Terminate
            certificateRefs:
            - name: gwapi-wildcard (5)
          allowedRoutes:
            namespaces:
              from: All
      1 The Gateway object must be created in the openshift-ingress namespace.
      2 The Gateway object must reference the name of the previously created GatewayClass object.
      3 The HTTPS listener listens for HTTPS requests that match a subdomain of the cluster domain. You use this listener to configure ingress to your applications by using Gateway API HTTPRoute resources.
      4 The hostname must be a subdomain of the ingress Operator domain. If you use a domain, the listener tries to serve all traffic in that domain.
      5 The name of the previously created secret.
    2. Apply the resource by running the following command:

      $ oc apply -f example-gateway.yaml
    3. Optional: When you create a Gateway object, Red Hat OpenShift Service Mesh automatically provisions a deployment and service with the same name. Verify this by running the following commands:

      • To verify the deployment, run the following command:

        $ oc get deployment -n openshift-ingress example-gateway-openshift-default
        Example output
        NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
        example-gateway-openshift-default    1/1     1            1           25s
      • To verify the service, run the following command:

        $ oc get service -n openshift-ingress example-gateway-openshift-default
        Example output
        NAME                                TYPE           CLUSTER-IP   EXTERNAL-IP         PORT(S)      AGE
        example-gateway-openshift-default   LoadBalancer   10.1.2.3     <external_ipname>   <port_info>  47s
    4. Optional: The ingress Operator automatically creates a DNSRecord CR using the hostname from the listeners, and adds the label gateway.networking.k8s.io/gateway-name=example-gateway. Verify the status of the DNS record by running the following command:

      $ oc -n openshift-ingress get dnsrecord -l gateway.networking.k8s.io/gateway-name=example-gateway -o yaml
      Example output
      kind: DNSRecord
        ...
      status:
        ...
        zones:
        - conditions:
          - message: The DNS provider succeeded in ensuring the record
            reason: ProviderSuccess
            status: "True"
            type: Published
          dnsZone:
            tags:
              ...
        - conditions:
          - message: The DNS provider succeeded in ensuring the record
            reason: ProviderSuccess
            status: "True"
            type: Published
          dnsZone:
            id: ...
  5. Create an HTTPRoute resource that directs requests to your already-created namespace and application called example-app/example-app:

    1. Create a YAML file, example-route.yaml, that contains the following information:

      Example HTTPRoute CR
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: example-route
        namespace: example-app-ns (1)
      spec:
        parentRefs: (2)
        - name: example-gateway
          namespace: openshift-ingress
        hostnames: ["example.gwapi.${DOMAIN}"] (3)
        rules:
        - backendRefs: (4)
          - name: example-app (5)
            port: 8443
      1 The namespace you are deploying your application.
      2 This field must point to the Gateway object you previously configured.
      3 The hostname must match the one specified in the Gateway object. In this case, the listeners use a wildcard hostname.
      4 This field specifies the backend references that point to your service.
      5 The name of the Service for your application.
    2. Apply the resource by running the following command:

      $ oc apply -f example-route.yaml
      Example output
      httproute.gateway.networking.k8s.io/example-route created
Verification
  1. Verify that the Gateway object is deployed and has the condition Programmed by running the following command:

    $ oc wait -n openshift-ingress --for=condition=Programmed gateways.gateway.networking.k8s.io example-gateway
    Example output
    gateway.gateway.networking.k8s.io/example-gateway condition met
  2. Send a request to the configured HTTPRoute object hostname:

    $ curl -I --cacert <local cert file> https://example.gwapi.${DOMAIN}:443

Gateway API deployment topologies

Gateway API is designed to accomodate two topologies: shared gateways or dedicated gateways. Each topology has its own advantages and different security implications.

Dedicated gateway

Routes and any load balancers or proxies are served from the same namespace. The Gateway object restricts routes to a particular application namespace. This is the default topology when deploying a Gateway API resource in OKD.

Shared gateway

Routes are served from multiple namespaces or with multiple hostnames. The Gateway object filters allow routes from application namespaces by using the spec.listeners.allowedRoutes.namespaces field.

Dedicated gateway example

The following example shows a dedicated Gateway resource, fin-gateway:

Example dedicated Gateway resource
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: fin-gateway
  namespace: openshift-ingress
spec:
  listeners: (1)
  - name: http
    protocol: HTTP
    port: 8080
    hostname: "example.com"
1 Creating a Gateway resource without setting spec.listeners[].allowedRoutes results in implicitly setting the namespaces.from field to have the value Same.

The following example shows the associated HTTPRoute resource, sales-db, which attaches to the dedicated Gateway object:

Example HTTPRoute resource
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: sales-db
  namespace: openshift-ingress
spec:
  parentRefs:
  - name: fin-gateway
  hostnames:
  - sales-db.example.com
  rules:
    - backendRefs:
        - name: sales-db
        ¦ port: 8080

The HTTPRoute resource must have the name of the Gateway object as the value for its parentRefs field in order to attach to the gateway. Implicitly, the route is assumed to be in the same namespace as the Gateway object.

Shared gateway example

The following example shows a Gateway resource, devops-gateway, that has a spec.listeners.allowedRoutes.namespaces label selector set to match any namespaces containing shared-gateway-access: "true":

Example shared Gateway resource
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: devops-gateway
  namespace: openshift-ingress
listeners:
  - name: https
    protocol: HTTPS
    hostname: "example.com"
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
        ¦ matchLabels:
        ¦   shared-gateway-access: "true"

The following examples show the allowed namespaces for the devops-gateway resource:

Example Namespace resources
apiVersion: v1
kind: Namespace
metadata:
  name: dev
  labels:
    shared-gateway-access: "true"
---
apiVersion: v1
kind: Namespace
metadata:
  name: ops
  labels:
    shared-gateway-access: "true"

In this example, two HTTPRoute resources, dev-portal and ops-home, are in different namespaces but are attached to the shared gateway:

apiVersion: v1
kind: HTTPRoute
metadata:
  name: dev-portal
  namespace: dev
spec:
  parentRefs:
  - name: devops-gateway
    namespace: openshift-ingress
  rules:
  - backendRefs:
    - name: dev-portal
      port: 8080
---
apiVersion: v1
kind: HTTPRoute
metadata:
  name: ops-home
  namespace: ops
spec:
  parentRefs:
  - name: devops-gateway
    namespace: openshift-ingress
  rules:
  - backendRefs:
    - name: ops-home
      port: 8080

With a shared gateway topology, the routes must specify the namespace of the Gateway object it wants to attach to. Multiple Gateway objects can be deployed and shared across namespaces. When there are multiple shared gateways, this topology becomes conceptually similar to ingress Controller sharding.

Additional resources