Chapter 3. Configuring Gateway API


3.1. Understand Gateway API

To optimize network traffic management and implement routing policies in OpenShift Container Platform, use Gateway API. By adopting this community-managed Kubernetes mechanism, you can configure advanced routing at both the transport (L4) and application (L7) layers while leveraging various vendor-supported implementations to meet your specific networking requirements.

A well-designed Gateway API deployment helps you achieve a portable, role-oriented routing infrastructure. To successfully plan your Gateway API implementation, review the following concepts:

  • Understand the benefits and limitations of Gateway API.
  • Review OpenShift Container Platform implementation specifics to avoid unsupported features.
  • Choose between shared or dedicated deployment topologies.
Important

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

3.1.1. Gateway API benefits and limitations

To determine if Gateway API is the right routing solution for your cluster, review its benefits and limitations. The project is an effort to provide a standardized ecosystem by using a portable API with broad community support. Understanding these factors ensures your networking infrastructure aligns with your organizational needs and technical capabilities.

3.1.1.1. Benefits

Gateway API provides the following benefits:

  • Portability: Where OpenShift Container Platform uses HAProxy to improve Ingress performance, Gateway API does not rely on vendor-specific annotations to provide certain behavior. To get comparable performance to 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 administrators 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.

3.1.1.2. Limitations

Gateway API has the following limitations:

  • Version incompatibilities: The 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.
  • On-premise infrastructure dependencies: On-premise deployments, such as bare metal or VMware vSphere environments, do not automatically provision network load balancers or manage external DNS records. To use Gateway API on an on-premise platform, you must explicitly deploy a load balancer controller, such as MetalLB, and manually map your DNS records to the provisioned gateway address.

3.1.2. Gateway API implementation specifics

To ensure interoperability between external vendor implementations and your networking infrastructure in OpenShift Container Platform, the Ingress Operator manages the lifecycle of Gateway API custom resource definitions (CRDs). Understanding how these CRDs are managed helps you prevent disrupted workloads and security issues caused by incompatible vendor fields.

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 OpenShift Container Platform uses a specific version of Gateway API CRDs, any use of third-party implementations of Gateway API must conform to the OpenShift Container Platform implementation to ensure that all fields work as expected.

Any CRDs created within an OpenShift Container Platform 4.22 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 OpenShift Container Platform, and creates an admin-gate that requires your acknowledgment of CRD succession.

Important

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

In previous versions of OpenShift Container Platform, cluster security policies blocked the deployment of the Gateway API CRD for gateway.networking.x-k8s.io. Starting in OpenShift Container Platform 4.22, this restriction is removed, and you can deploy that CRD.

Note

Experimental Gateway API CRDs in the gateway.networking.k8s.io group remain restricted.

You can install the gateway.networking.x-k8s.io CRD and related objects on the cluster because they are no longer blocked. The built-in Gateway API implementation managed by the Ingress Operator does not reconcile those objects in OpenShift Container Platform. Use a compatible third-party Gateway implementation if you need those APIs reconciled.

3.1.3. Gateway API deployment topologies

To effectively organize and secure your routing infrastructure, you must choose an appropriate deployment topology for your cluster. Gateway API is designed to accommodate two topologies: shared gateways or dedicated gateways. You can choose a topology based on its own advantages and different security implications.

3.1.3.1. 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 OpenShift Container Platform.

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:
  gatewayClassName: openshift-default
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    hostname: "example.com"

If you do not set spec.listeners[].allowedRoutes for a Gateway resource, the system implicitly sets the namespaces.from field to the value of 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 to attach to the gateway. The system implicitly assumes that the route exists in the same namespace as the Gateway object.

3.1.3.2. Shared gateway

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

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
spec:
  gatewayClassName: openshift-default
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    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.

3.2. Enable Gateway API

To route traffic using Gateway API, you must first enable the feature on your cluster. You can enable Gateway API by creating a GatewayClass custom resource, which triggers the Ingress Operator to provision the necessary controller and components.

After you successfully enable Gateway API, you can begin deploying gateways, assigning network addresses, and configuring listeners to control your network traffic flow.

3.2.1. Enable Gateway API for the Ingress Operator

To configure Gateway API for use on your cluster, you must create a GatewayClass resource. During the creation of the GatewayClass resource, the Ingress Operator installs a lightweight Istio control plane, based on Red Hat OpenShift Service Mesh, in the openshift-ingress namespace.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).

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

      • metadata.name: The name of your GatewayClass object. The name must consist of a maximum of 63 lowercase alphanumeric characters or hyphens (-). The name must also start and end with an alphanumeric character.

        Important

        The controllerName value 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 OpenShift Container Platform, 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

Verification

  • Verify that the GatewayClass CR has been accepted and the controller is successfully installed by running the following command:

    $ oc get gatewayclass openshift-default -o yaml

    Example output

    # ...
    status:
      conditions:
      - lastTransitionTime: "2026-05-15T10:00:00Z"
        message: The GatewayClass has been accepted
        reason: Accepted
        status: "True"
        type: Accepted
      - lastTransitionTime: "2026-05-15T10:00:00Z"
        message: Istio installed successfully
        reason: Installed
        status: "True"
        type: ControllerInstalled
      - lastTransitionTime: "2026-05-15T10:00:00Z"
        message: Istio CRDs are being managed by cluster-ingress-operator
        reason: ManagedByCIO
        status: "True"
        type: CRDsReady
    # ...

    Inspect the status.conditions block in the output. A healthy GatewayClass CR reports a status of True for the Accepted, ControllerInstalled, and CRDsReady conditions.

To control network traffic flow, you can configure Gateway API listeners to define the designated port, protocol, and hostname for your gateway. By configuring listeners, you can specify secure TLS connections, dictate how traffic is terminated, and restrict which application routes are permitted to attach to the gateway.

To successfully manage your incoming traffic with gateway listeners, complete the following tasks:

  • Configure listener routing and security settings to define the ports, protocols, hostnames, and TLS certificates for your incoming traffic.
  • Understand listener routing conflicts by applying conflict management rules to ensure overlapping hostnames or ports are routed correctly.
  • Troubleshoot listener connections by monitoring listener status conditions to identify and resolve configuration errors.

To ensure that your applications receive only authenticated and authorized traffic, you must specify the allowed protocols and ports for your gateway. If you are routing secure traffic, you must also configure TLS settings. You can define these parameters by configuring the spec.listeners field in your Gateway custom resource (CR).

Procedure

  1. Create or edit a Gateway YAML file to include your desired listener configuration.

    The following example demonstrates a Gateway CR with two listeners, one for HTTP and one for HTTPS. For detailed descriptions of the listener fields, see Section 3.3.1.1, “Gateway listener configuration reference”.

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: <example_gateway>
      namespace: openshift-ingress
    spec:
      gatewayClassName: openshift-default
      listeners:
      - protocol: HTTP 
        port: 80
        name: http
        allowedRoutes: 
          namespaces:
            from: Selector
            selector:
              matchLabels:
                env: "dev"
      - protocol: HTTPS 
        port: 443
        name: https
        hostname: "*.<example_domain.tld>" 
        tls: 
          mode: Terminate
          certificateRefs:
            - name: <listener_cert>
              kind: Secret
        allowedRoutes: 
          namespaces:
            from: All
  2. Apply the Gateway CR by running the following command:

    $ oc apply -f <gateway_cr>.yaml

3.3.1.1. Gateway listener configuration reference

When configuring the spec.listeners field in your Gateway custom resource (CR), you can define network protocols, ports, hostnames, TLS termination, and route attachment policies.

You can customize your gateway listener configuration using the following fields:

spec.listeners
Defines the list of listeners for the gateway. You can customize this field with settings for port, protocol, TLS, hostnames, and allowed routes.
listeners.protocol and listeners.port
Defines the network port and protocol. For example, protocol: HTTP accepts HTTP traffic on port 80, and protocol: HTTPS accepts HTTPS traffic on port 443.
listeners.hostname
Defines the hostnames that the listener matches for incoming requests. For example, it can match only requests for hostnames ending in <example_domain.tld> (such as www.<example_domain.tld>). If no hostname is specified, the gateway routes any traffic that can attach to it.
listeners.tls
Specifies the TLS settings for secure communication, including the mode (currently, only Terminate is supported on OpenShift Container Platform) and the Kubernetes secret containing the certificate keypair. For example, TLS is terminated at the gateway using a certificate stored in a Kubernetes Secret called <listener_cert>. You must ensure that the specified Kubernetes secret exists before you create the Gateway CR.
listeners.allowedRoutes
Controls which Route resources can attach to this listener. For example, an HTTP listener might only allow HTTPRoute resources from namespaces that have the env: "dev" label (using Selector), while an HTTPS listener might allow HTTPRoute resources from any namespace to attach (using All). Setting allowedRoutes.namespaces.from: Same is not supported; routes from the same namespace as the gateway are always allowed.

3.3.2. Understand listener routing conflicts

When you configure a Gateway custom resource (CR) with multiple listeners, you must establish clear rules for overlapping hostnames and ports to ensure your traffic does not get misrouted. To avoid ambiguity, the Gateway API uses specific conflict management rules.

If your listener configurations violate these rules, the affected listener receives a Conflicted status condition and cannot route traffic correctly. 

To resolve or prevent routing conflicts, ensure that your listeners adhere to the following rules:

  • Distinct ports: A gateway can have distinct listeners that use the exact same hostname, provided their network ports are distinct.
  • Distinct hostnames: A gateway can have distinct listeners that use the exact same protocol and port, provided their hostnames are different.
  • Specificity precedence: If one listener uses a wildcard domain (for example, *.<example_domain.tld>) and another listener uses a more specific endpoint for that exact same domain (for example, <www.example_domain.tld>), the more specific entry takes precedence. 

    This specificity rule also applies to multiple wildcard domains. For example, *.<example_domain.tld> takes precedence over *.<tld>. This ensures that traffic intended for a specific subdomain is accurately routed to its dedicated listener, even if a broader wildcard listener exists.

    Note

    In the Gateway API, wildcards match one or more complete DNS labels. For example, *.<example.com> matches <www.example.com> and <sub.domain.example.com>, but does not match the root domain <example.com>.

When a listener is not routing traffic as expected, you can review its status conditions to quickly diagnose and fix the configuration error. The listener status condition gives insight into its current state and any underlying issues preventing it from accepting traffic.

Procedure

  1. Check the status conditions of your Gateway custom resource (CR) by running the following command:

    $ oc describe gateway <gateway_cr> -n <namespace>

When you troubleshoot your gateway listeners, you can review the status conditions in the Gateway custom resource (CR) output to identify configuration errors or conflicts.

The following table describes common listener conditions and how to resolve them:

Expand
Table 3.1. Gateway listener status conditions
ConditionDescription

Ready

Indicates that the listener is configured correctly and is actively listening for traffic.

Conflicted

Signifies an ambiguity or conflict in the listener’s configuration with another listener on the same gateway. If a listener is conflicted, review your listener configurations against the conflict management rules to identify and resolve the ambiguity.

Programmed

Denotes that the underlying infrastructure, such as a load balancer or proxy, has successfully been programmed with the listener’s configuration.

Accepted

Indicates that the gateway has accepted the listener’s configuration. This is usually an early step in the listener’s lifecycle.

Invalid

Means the listener’s configuration itself contains errors or is malformed, preventing it from being processed. An invalid status indicates errors in your YAML configuration. Check your configuration for typos, incorrect syntax, or missing required fields.

3.4. Assign network addresses to gateways

You can configure network addresses for your gateway to provide a predictable entry point for external and internal traffic. This ensures that clients can reliably resolve and route requests to your load balancers.

Gateway API uses addresses to define the specific network locations that are assigned to your Gateway resource. In OpenShift Container Platform, you rely on the gateway controller to automatically provision and bind the necessary network addresses, such as an external or internal load balancer IP, to your gateway. On on-premise environments, this automatic provisioning requires a configured load balancer controller.

To successfully assign network addresses to your gateway, complete the following tasks:

  • Understand gateway address assignment and types to plan your DNS and load balancer configuration.
  • Understand on-premise gateway routing requirements to ensure your infrastructure can support Gateway API.
  • Configure automatic address assignment for a gateway to successfully deploy it without violating manual address constraints.
  • Configure an internal load balancer to restrict your gateway traffic to your private network.
  • Review cloud provider annotations to ensure your internal load balancer provisions correctly on your specific infrastructure.
  • Configure DNS for on-premise gateways to ensure clients can reliably resolve your gateway.

OpenShift Container Platform automatically handles address assignment by provisioning a LoadBalancer service when you create a Gateway resource. The network address assigned to your gateway corresponds to the IP address or hostname of this underlying load balancer.

Important

Do not define the spec.addresses field. Manually requesting specific network addresses is not currently supported in OpenShift Container Platform. If you attempt to request a specific address manually, the gateway enters an error state.

The status.addresses field is populated automatically by the gateway controller. This field lists the actual, active network address assigned to your gateway by the load balancing infrastructure.

3.4.1.1. Address types

When the controller dynamically assigns an address to your gateway and populates the status.addresses field, it uses one of the following primary types to reflect the underlying load balancer:

Hostname
Represents a DNS-based ingress point. This concept is typically used for cloud load balancers where a DNS name exposes the load balancer.
IPAddress
A textual representation of a numeric IP address (IPv4 or IPv6) assigned by the load balancing infrastructure.

3.4.2. On-premise gateway routing requirements

Understand the specific routing and load balancing requirements for on-premise Gateway API deployments to ensure your gateway functions correctly.

Unlike cloud environments where load balancers are dynamically provisioned, on-premise clusters require a preconfigured load balancer controller. Red Hat tests and certifies Gateway API on on-premise platforms specifically with MetalLB.

Warning

If you attempt to use Gateway API on an on-premise cluster without a functional load balancer controller, the gateway service will remain in a "pending" state indefinitely.

Additionally, be aware of the following topology and load balancer limitations for on-premise environments:

  • Third-party load balancers: Red Hat does not currently test Gateway API with third-party load balancers such as F5 or Avi Kubernetes Operator (AKO). If you use an untested load balancer, the cluster administrator is responsible for ensuring it is configured and working properly.
  • Unsupported topologies: Environments without a load balancer controller are not supported. For example, you cannot use annotations to enforce a NodePort service type in place of a load balancer.

When you create a gateway resource, you must configure it for automatic address provisioning to successfully deploy the gateway without violating OpenShift Container Platform manual address constraints. By intentionally omitting the addresses field, you allow the controller to seamlessly provision and bind the necessary external network addresses to your gateway.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have an existing GatewayClass resource, such as openshift-default.

Procedure

  1. Create a YAML file, such as hello-gateway.yaml, that defines your Gateway object without the addresses field:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: sample-gateway
      namespace: openshift-ingress
    spec:
      gatewayClassName: openshift-default
      listeners:
      - name: http
        hostname: "*.gwapi.<cluster_domain>"
        port: 80
        protocol: HTTP
        allowedRoutes:
          namespaces:
            from: All
    • metadata.name: The name of your Gateway object. The name must consist of a maximum of 63 lowercase alphanumeric characters or hyphens (-). The name must also start and end with an alphanumeric character.
    • Replace <cluster_domain> with your actual cluster ingress domain (for example, example.com).
    • The spec.addresses field is omitted from this configuration to ensure automatic assignment.
    • The gatewayClassName dictates which controller provisions the address and populates the status.addresses field.
  2. Apply the Gateway configuration by running the following command:

    $ oc apply -f hello-gateway.yaml
  3. Verify that the controller automatically assigned an address to your gateway by running the following command:

    $ oc -n openshift-ingress get gateway sample-gateway

    Example output

    NAME             CLASS               ADDRESS             PROGRAMMED   AGE
    sample-gateway   openshift-default   <gateway_address>   True         6m16s

    The ADDRESS column in the output displays the dynamically provisioned network address for your gateway.

By default, Gateway API provisions an external load balancer. To restrict your gateway traffic to your private network, you can configure Gateway API to provision an internal load balancer by adding a cloud-specific annotation to your Gateway custom resource (CR).

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have configured a GatewayClass object.

Procedure

  1. Create or edit your Gateway CR to include the cloud-specific annotation under spec.infrastructure.annotations.

    The following example provisions an internal load balancer for an AWS cluster:

    Example Gateway CR for an AWS internal load balancer

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mygateway
      namespace: openshift-ingress
    spec:
      gatewayClassName: openshift-default
      infrastructure:
        annotations:
        # Specifies the cloud provider annotation and value required to provision an internal load balancer:
          service.beta.kubernetes.io/aws-load-balancer-internal: "true"
      listeners:
      - name: https
        hostname: "*.example.com"
        port: 443
        protocol: HTTPS
        tls:
          mode: Terminate
          certificateRefs:
          - name: gateway-tls-secret
    # ...

  2. Apply the updated Gateway CR by running the following command:

    $ oc apply -f <gateway_filename>.yaml

Verification

  • Verify that the load balancer service is provisioned and has an internal IP address by running the following command:

    $ oc -n openshift-ingress get svc

To provision an internal load balancer for clusters deployed in private environments, you must add specific annotations to the spec.infrastructure.annotations field of your Gateway custom resource (CR).

This configuration is supported on Amazon Web Services (AWS), Microsoft Azure, Google Cloud, Red Hat OpenStack Platform (RHOSP), and IBM Cloud. The following table details the required cloud-specific annotations and their corresponding values.

Expand
Table 3.2. Internal load balancer annotations by cloud provider
Cloud ProviderAnnotationValue

AWS

service.beta.kubernetes.io/aws-load-balancer-internal

"true"

Azure

service.beta.kubernetes.io/azure-load-balancer-internal

"true"

Google Cloud

cloud.google.com/load-balancer-type

"Internal"

RHOSP

service.beta.kubernetes.io/openstack-internal-load-balancer

"true"

IBM Cloud/ IBM Power Virtual Server

service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type

"private"

3.4.5. Configuring DNS for on-premise gateways

Configure DNS records manually on on-premise environments to ensure clients can reliably resolve your gateway.

Although the Ingress Operator automatically creates a DNSRecord custom resource (CR) using the hostname from the listener, this record is marked as "unmanaged" on on-premise platforms because the cluster Ingress Operator does not implement on-premise DNS providers. You must manually configure DNS records to point to the IP address of your load balancer.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have configured a load balancer controller, such as MetalLB, for your cluster.
  • Your gateway has been assigned an external network address by the load balancer.
  • Your gateway is located in the openshift-ingress namespace.

Procedure

  1. Retrieve the external IP address assigned to your gateway by the load balancer by running the following command:

    $ oc -n openshift-ingress get gateway <gateway_name>

    Note the IP address listed in the ADDRESS column.

  2. Access your organization’s DNS provider or server.
  3. Create a DNS record, such as an A record or wildcard A record, that maps the listener’s hostname to the external IP address of your gateway.

3.5. Routing HTTP requests to services

When you expose your applications through a gateway, you must configure an HTTPRoute custom resource (CR) to accurately direct incoming HTTP requests from your network listener to the appropriate backend services. A Gateway API HTTPRoute CR specifies the exact routing behavior for these requests by evaluating a set of rules.

The core configuration element of an HTTPRoute CR is a rule. You can configure up to 16 rules for a single route. Within each rule, you can establish the following routing behaviors:

  • Matches: Define the conditions an HTTP request must meet based on paths, headers, query parameters, or methods. 
  • Filters: Apply processing directions to the request, such as header modifications, mirrors, or redirects.
  • BackendRefs: Designate the backend services where matching and filtered requests are delivered, including traffic weight distribution.
  • Timeouts: Establish strict time limits for the entire request or the backend hop.

To successfully configure your HTTP routing behavior, complete the following tasks:

  • Configure HTTP request matching conditions
  • Apply processing filters to HTTP requests
  • Configure routing destinations and traffic weights
  • Set timeouts for HTTP requests
  • Compare OpenShift Container Platform routes and HTTPRoute CRs

3.5.1. Configure HTTP request matching conditions

To ensure traffic is routed to the correct application when multiple services share a gateway, you can define request matching conditions within your HTTPRoute custom resource (CR). You can match HTTP requests based on paths, headers, query parameters, or methods.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).

Procedure

  1. Create or edit an HTTPRoute YAML file to include your desired match conditions under the spec.rules.matches field. 

    The following example demonstrates a complete HTTPRoute custom resource (CR) configured with path-based matching to route requests for /<example_app> to a backend service. For details on configuring other match types, see Section 3.5.1.1, “Supported HTTPRoute match types”.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: <path_match_example>
      namespace: <example_application>
    spec:
      parentRefs:
      - name: <example_gateway>
        namespace: openshift-ingress
      hostnames:
      - "<example.com>"
      rules:
      - matches:
        - path:
            type: Exact
            value: /<example_app>
        backendRefs:
        - name: <example_backend>
          port: 8080
  2. Apply the HTTPRoute CR by running the following command:

    $ oc apply -f <filename>.yaml

3.5.1.1. Supported HTTPRoute match types

Matches define conditions used for matching the rule against incoming HTTP requests. If no match is specified, then all HTTP requests are matched, depending on the hostname. Each match is independent, i.e. this rule will be matched if any single match of the type is satisfied. A rule may have up to 64 matches, but most rules don’t need to be this complex. You may combine multiple match types (path and headers, for example), all of which must be true in order for the HTTP request to match.

You can configure the following match types:

path
Consists of type and value. Path match type indicates how to match the value and may be either “Exact” or “PathPrefix” (default). The default path value, if omitted, is “/”. On Red Hat OpenShift Service Mesh, “RegularExpression” may also be used as a type.
headers
Each consists of type, name, and value. Header match type indicates how to match the value and may be “Exact” (default) or on Red Hat OpenShift Service Mesh, “RegularExpression”. Name is the HTTP header name, which must be case-insensitive. Value is the value of the HTTP header to be matched.
queryParameters
Each consists of type, name, and value. QueryParameters match type indicates how to match the value and may be “Exact” (default) or on Red Hat OpenShift Service Mesh, “RegularExpression”. Name is the HTTP query parameter name and must match exactly. Value is the value of the HTTP query parameter to be matched.
method
A value in upper case that should match on the HTTP request method. Must be one of: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, or PATCH.
Note

According to Gateway API conventions, the RegularExpression match type is classified as an implementation-specific feature (Support: Implementation-specific). While Red Hat OpenShift Service Mesh fully supports regular expression matching, this feature might not be available or behave identically across other Gateway API implementations.

3.5.1.1.1. Example: path match

The following example demonstrates a complete HTTPRoute custom resource (CR) configured with path-based matching to route requests for /<example_app> to a backend service:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: <path_match_example>
  namespace: <example_application>
spec:
  parentRefs:
  - name: <example_gateway>
    namespace: openshift-ingress
  hostnames:
  - "<example.com>"
  rules:
  - matches:
    - path:
        type: Exact
        value: /<example_app>
    backendRefs:
    - name: <example_backend>
      port: 8080
  • path specifies that the request must match a specific URL path.
  • type: Exact ensures the route only matches the exact string /<example_app>.
  • backendRefs defines the service where matching traffic is sent.
3.5.1.1.2. Example: headers match (AND condition)

The following snippet demonstrates how to combine multiple header matches so that a request must contain both myheader: newheader AND color: orange to successfully match:

spec:
  rules:
  - matches:
    - headers:
      - name: <my_header>
        value: <new_header_value>
      - name: <color_header>
        value: <orange_value>
    backendRefs:
    - name: <example_service>
      port: 8080

3.5.2. Apply processing filters to HTTP requests

To modify how HTTP requests are processed before they reach your backend services, you can pre-configure filters within the rules of your HTTPRoute custom resource (CR). Configuring these filters allows you to automatically redirect traffic, modify headers, or mirror requests to achieve your desired routing behavior.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).

Procedure

  1. Create or edit an HTTPRoute YAML file to include your desired processing directives under the spec.rules.filters field. 

    The following example demonstrates a complete HTTPRoute custom resource (CR) with a requestRedirect filter that issues a permanent redirect (301) from HTTP to HTTPS. For details on configuring other filter types, see Section 3.5.2.1, “Supported HTTPRoute filters”.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: <http_filter_example>
      namespace: <example_application>
    spec:
      parentRefs:
      - name: <example_gateway>
        namespace: openshift-ingress
      hostnames:
      - "<example.com>"
      rules:
      - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 301
  2. Apply the HTTPRoute CR by running the following command:

    $ oc apply -f <filename>.yaml

3.5.2.1. Supported HTTPRoute filters

Filters apply processing directions to the HTTP request, such as header modification or redirect to another URL. You can specify up to 16 filters in a rule. Filters may usually be combined for advanced filtering results, except for the urlRewrite and requestRedirect filters, which may not be combined.

You can apply the following filter types to a rule:

requestRedirect
Responds to an HTTP request with an HTTP 3xx code, instructing the client to retrieve another URL. Optional fields include scheme (http | https), hostname, path (type: replaceFullPath | replacePrefixMatch, string values for replaceFullPath or replacePrefixMatch), port, and statusCode (301 | 302 | 303 | 307 | 308).
requestHeaderModifier
Modifies an HTTP request’s headers. Only one modifier per header may be specified. Multiple values for a header must be comma-separated. Up to 16 header filters may be listed. Fields are one of Set, Add, Remove. Set, Add, and Remove may modify, add, and remove up to 16 header values that match a given name.
responseHeaderModifier
Available on Red Hat OpenShift Service Mesh, this extended filter modifies an HTTP response’s headers with the same constraints as requestHeaderModifier.
requestMirror
Available on Red Hat OpenShift Service Mesh, this extended filter mirrors (i.e. sends a duplicate) requests to specified destinations (backendRef). Fields include: backendRef, and the optional percent or fraction to specify the portion of requests that should be mirrored. If neither percent nor fraction are specified, then 100% of requests are mirrored.
urlRewrite
Available on Red Hat OpenShift Service Mesh, this extended filter modifies an HTTP request’s hostname, path, or both. It may not be used in combination with the requestRedirect filter. However, the path semantics for requestRedirect can also be used for urlRewrite, i.e. (type: replaceFullPath | replacePrefixMatch, string values for replaceFullPath or replacePrefixMatch).
3.5.2.1.1. Example: requestRedirect filter

The following example demonstrates a complete HTTPRoute custom resource (CR) with a requestRedirect filter that issues a permanent redirect (301) from HTTP to HTTPS:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: <http_filter_example>
  namespace: <example_application>
spec:
  parentRefs:
  - name: <example_gateway>
    namespace: openshift-ingress
  hostnames:
  - "<example.com>"
  rules:
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        statusCode: 301
  • hostnames defines the domain, such as "<example.com>", that this route applies to.
  • filters specifies the processing logic. In this example, the RequestRedirect type is used.
  • scheme: https instructs the gateway to redirect the client to the secure version of the URL.
  • statusCode: 301 indicates a permanent redirect.
3.5.2.1.2. Example: requestHeaderModifier filter

The following snippet demonstrates how to configure a requestHeaderModifier filter that adds a new header, modifies an existing header, and removes a specific header:

spec:
  rules:
  - filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        add:
        - name: <my_header_name>
          value: <my_header_value>
    - type: RequestHeaderModifier
      requestHeaderModifier:
        set:
        - name: <old_header>
          value: <new_header_value>
    - type: RequestHeaderModifier
      requestHeaderModifier:
        remove: ["x-request-id"]

To route traffic to your backends, you must define service destinations and traffic weights within your HTTPRoute custom resource (CR) to distribute requests across your applications.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).

Procedure

  1. Create or edit an HTTPRoute YAML file to include your desired service destinations under the spec.rules.backendRefs field.

    The following example demonstrates a complete HTTPRoute custom resource (CR) with a single backend destination that routes traffic to a service named <service_v1>. For details on configuring weights and routing to multiple destinations, see Section 3.5.3.1, “HTTPRoute backendRef configuration”.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: <backend_route_example>
      namespace: <example_application>
    spec:
      parentRefs:
      - name: <example_gateway>
        namespace: openshift-ingress
      rules:
      - backendRefs:
        - name: <service_v1>
          port: 8080
  2. Apply the HTTPRoute CR by running the following command:

    $ oc apply -f <filename>.yaml

3.5.3.1. HTTPRoute backendRef configuration

BackendRefs are the service destinations of requests that meet your matches rules, and are composed of group, kind, name, namespace, port, and weight. Name and port are the only required fields and refer to the service name and the service port number Weight is relevant when there is more than one backendRef, and specifies the proportion of requests forwarded to that specific backendRef. Without a backendRef, the rule doesn’t do any request forwarding and may return an error.

3.5.3.1.1. Example: Single backend destination

This example shows a BackendRef where there is a single backend destination, a service named <service_v1>:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: <backend_route_example>
  namespace: <example_application>
spec:
  parentRefs:
  - name: <example_gateway>
    namespace: openshift-ingress
  rules:
  - backendRefs:
    - name: <service_v1>
      port: 8080
  • backendRefs defines the destination services for the traffic.
  • name specifies the name of the Kubernetes service.
  • port specifies the port on which the service is listening.
3.5.3.1.2. Example: Weighted backend delivery

This example shows two backendRefs where there is weighted delivery of 15 and 25 for the backends. This means <service_v1> gets 15/40 (3/8ths) of the traffic, and <service_v2> gets 25/40 (5/8ths) of the traffic. Though not required, it is recommended to have the weights add up to 100 whenever possible for clarity.

spec:
  rules:
  - backendRefs:
    - name: <service_v1>
      port: 8080
      weight: 15
    - name: <service_v2>
      port: 8080
      weight: 25

3.5.4. Set timeouts for HTTP requests

To prevent hanging connections and ensure your application remains responsive, you can set strict timeouts for the entire request and the backend hop within your HTTPRoute custom resource (CR).

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).

Procedure

  1. Create or edit an HTTPRoute YAML file to include your desired timeout configurations under the spec.rules.timeouts field.

    The following example demonstrates a complete HTTPRoute custom resource (CR) where the entire request must complete within 30 seconds. For details on timeout formatting rules and backend request timeouts, see Section 3.5.4.1, “HTTPRoute timeout configuration”.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: <timeout_example>
      namespace: <example_application>
    spec:
      parentRefs:
      - name: <example_gateway>
        namespace: openshift-ingress
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /<timeout_path>
        timeouts:
          request: 30s
        backendRefs:
        - name: <example_service>
          port: 8080
  2. Apply the HTTPRoute CR by running the following command:

    $ oc apply -f <filename>.yaml

3.5.4.1. HTTPRoute timeout configuration

There are two types of timeouts you can configure for an HTTPRoute custom resource (CR): request and backendRequest.

The request timeout covers the total time to send a request and then get a response back to the client. It represents the duration of the entire request-response transaction. 

The backendRequest timeout covers the time for a request to travel from the gateway to the backend, and for a response to be received. Extending the timeout for a backendRequest can be helpful if the gateway needs to retry connections to a backend.

Note

The backendRequest timeout is classified as an extended feature (Support: Extended) according to Gateway API conventions.

When configuring timeouts, you must adhere to the following formatting rules and constraints:

  • The value of a backendRequest timeout cannot be greater than the value of the request timeout.
  • If specified, a timeout value must be 0 or greater than or equal to 1ms
  • A zero-valued timeout (0) means there is no timeout.
  • Timeouts use a string format that starts with a number and expresses hours (h), minutes (m), seconds (s), or milliseconds (ms).
  • The number can be up to five digits, such as 10000s
  • You can use multipart durations to express fractions, such as 1m30s, but you cannot use decimal dots.
3.5.4.1.1. Example: Request timeout

The following example demonstrates a complete HTTPRoute custom resource (CR) where the entire request must complete within 30 seconds:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: <timeout_example>
  namespace: <example_application>
spec:
  parentRefs:
  - name: <example_gateway>
    namespace: openshift-ingress
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /<timeout_path>
    timeouts:
      request: 30s
    backendRefs:
    - name: <example_service>
      port: 8080
  • request specifies the timeout for the full request-response cycle.
  • PathPrefix ensures the timeout applies to all requests starting with /<timeout_path>.

The following snippet demonstrates a configuration where the request must succeed within 5 seconds, and the gateway-to-backend hop must complete within 1 second:

spec:
  rules:
  - timeouts:
      request: 5s
      backendRequest: 1s
    backendRefs:
    - name: <example_service>
      port: 8080

When you migrate from standard networking to the Gateway API, you can compare OpenShift Container Platform routes with HTTPRoute custom resources (CRs) to understand which features are supported and how your configuration must change. While both resources handle ingress traffic, they have distinct feature sets and implementation differences.

The following features are exclusive to HTTPRoute CRs:

  • Multiple hostnames
  • Matching based on HTTP headers
  • Matching based on query parameters
  • Request header modification
  • Request redirection
  • Request mirroring

The following features are exclusive to OpenShift Container Platform routes:

  • IP allow lists
  • Rate limiting (connection-based)
  • Subdomain indication
  • Re-encrypt TLS termination
  • Passthrough TLS termination

The following table outlines the features that are shared between both resources and how their specific implementations differ:

Expand
Table 3.3. Shared features and implementation differences
FeatureOpenShift Container Platform route implementationHTTPRoute implementation

Path matching

Supports prefix and exact matching.

Supports prefix, exact, and regular expression matching.

Backend references

Supports weighted traffic delivery to services.

Supports weighted traffic delivery to services via backendRefs.

Rewrite target

Configured using the haproxy.router.openshift.io/rewrite-target annotation.

Configured using the URLRewrite filter.

Sharding

Configured using metadata labels.

Configured using parent references (parentRefs).

3.6. Route gRPC requests to services

When you expose your gRPC APIs through a gateway, you must configure a GRPCRoute resource to accurately direct incoming gRPC requests from a Gateway listener to an API object. A GRPCRoute specifies the exact routing behavior for these requests by evaluating a set of defined rules.

Within each GRPCRoute rule, you can establish the following routing behaviors:

  • matches: Define the conditions a gRPC request must meet based on specific gRPC methods and headers.
  • filters: Apply processing directions to the request, such as header modifications, before the traffic reaches the backend.
  • backendRefs: Designate the backend services where matching and filtered requests are delivered, including traffic weight distribution.

While standard GRPCRoute configurations share many similarities with HTTPRoute resources, the OpenShift Container Platform implementation of GRPCRoute adheres to the standard-channel Gateway API specification, which excludes upstream experimental fields and features.

To successfully configure your gRPC routing behavior, complete the following tasks:

  • Configure gRPC request matching conditions
  • Apply processing filters to gRPC requests
  • Configure routing destinations and traffic weights for gRPC
  • Understand GRPCRoute implementation details

3.6.1. Configure gRPC request matching conditions

When multiple gRPC services share a gateway, you can define request matching conditions based on gRPC methods and headers. This ensures that traffic is successfully routed to the correct backend application.

Matches define the specific conditions used for matching a rule against incoming gRPC requests. You can select gRPC requests via a method match, which can be an exact match or a regular expression, along with optional headers matches.

Each rule can specify a maximum of 64 matches. However, the total number of matches across all rules in a single GRPCRoute resource cannot exceed 128. If your routing requirements exceed this limit, you must distribute your complex matching combinations across multiple routes.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have installed Red Hat OpenShift Service Mesh.

Procedure

  1. Create or edit a GRPCRoute YAML file to include your desired match conditions under the spec.rules.matches field.

    The following example demonstrates a complete GRPCRoute resource configured with matching conditions for a specific gRPC service, method, and header:

    apiVersion: gateway.networking.k8s.io/v1
    kind: GRPCRoute
    metadata:
      name: grpc-match-example
      namespace: my-application
    spec:
      parentRefs:
      - name: my-gateway
        namespace: openshift-ingress
      hostnames:
      - "example.com"
      rules:
      - matches:
        - method:
            service: helloworld.Greeter
            method: SayHello
          headers:
          - name: x-version
            value: v1
        backendRefs:
        - name: greeter-service
          port: 50051
          weight: 1
    • parentRefs attaches the route to the my-gateway Gateway.
    • method specifies that the incoming request must be targeting the helloworld.Greeter service and specifically calling the SayHello method.
    • headers requires that the request must also include an x-version header with a value of v1. Both the method and header conditions must be met for this rule to apply.
    • backendRefs routes the matching traffic to the greeter-service backend.
  2. Apply the GRPCRoute resource by running the following command:

    $ oc apply -f <filename>.yaml

3.6.2. Apply processing filters to gRPC requests

When a gRPC request hits your route, you can apply processing filters to modify the request or response before the traffic reaches your backend.

You can define optional filters within your routing rules to apply processing directives, such as request and response header modifiers or traffic mirroring. You can also specify rule-scoped filters directly within your backend references.

Because the data-plane behavior is provided by Red Hat OpenShift Service Mesh, you must validate specific feature support, such as filter capabilities and header matching, against your installed Service Mesh release.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have installed Red Hat OpenShift Service Mesh.

Procedure

  1. Create or edit a GRPCRoute YAML file to include your desired processing directives under the spec.rules.filters field.

    The following example demonstrates a complete GRPCRoute resource configured with a filter that adds a custom request header before routing to the backend service:

    apiVersion: gateway.networking.k8s.io/v1
    kind: GRPCRoute
    metadata:
      name: grpc-filter-example
      namespace: my-application
    spec:
      parentRefs:
      - name: my-gateway
        namespace: openshift-ingress
      hostnames:
      - "example.com"
      rules:
      - filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
            - name: custom-grpc-header
              value: my-custom-value
        backendRefs:
        - name: greeter-service
          port: 50051
    • parentRefs attaches the route to a specific Gateway.
    • hostnames limits the route to requests intended for "example.com".
    • filters specifies the processing logic. In this example, the RequestHeaderModifier adds a custom header to the gRPC request before it reaches the backend.
    • backendRefs directs the modified traffic to the greeter-service backend on port 50051.
  2. Apply the GRPCRoute resource by running the following command:

    $ oc apply -f <filename>.yaml

When you route gRPC traffic, you must define backend service destinations and traffic weights to distribute requests across your APIs. BackendRefs designate the backend services where matching and filtered gRPC requests are delivered.

You can configure optional backend references for each routing rule. By defining multiple backend references and assigning a weight to each, you can control the proportion of gRPC traffic that is forwarded to specific versions of your service. The proportion of traffic sent to a specific backend is calculated by dividing its assigned weight by the sum of all weights across all backends configured in the rule.

Because Red Hat OpenShift Service Mesh handles the data-plane behavior, you must ensure that your GRPCRoute references an Istio ingress gateway in its parentRefs configuration.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • You have installed Red Hat OpenShift Service Mesh.

Procedure

  1. Create or edit a GRPCRoute YAML file to include your desired service destinations and traffic weights under the spec.rules.backendRefs field.

    The following example demonstrates a complete GRPCRoute resource that routes gRPC traffic between two versions of a backend service using proportional traffic weights:

    apiVersion: gateway.networking.k8s.io/v1
    kind: GRPCRoute
    metadata:
      name: grpc-weight-example
      namespace: my-application
    spec:
      parentRefs:
      - name: my-gateway
        namespace: openshift-ingress
      hostnames:
      - "example.com"
      rules:
      - backendRefs:
        - name: greeter-service-v1
          port: 50051
          weight: 90
        - name: greeter-service-v2
          port: 50051
          weight: 10
    • parentRefs attaches the route to the my-gateway Gateway.
    • backendRefs defines the destination services for the traffic.
    • weight dictates the traffic split. In this configuration, the total sum of the weights is 100. The route forwards 90% of the traffic to greeter-service-v1 and 10% to greeter-service-v2.
  2. Apply the GRPCRoute resource by running the following command:

    $ oc apply -f <filename>.yaml

3.6.4. GRPCRoute implementation details

The OpenShift Container Platform Cluster Ingress Operator vendors the standard-channel Gateway API v1.4.1 custom resource definition (CRD). When you migrate upstream GRPCRoute configurations to your cluster, you must ensure your manifests rely on standard-channel features to avoid validation errors.

Additionally, the cluster-ingress-operator only installs the GRPCRoute CRD and delegates all runtime semantics to Red Hat OpenShift Service Mesh. Because the operator does not reconcile GRPCRoute instances, the data-plane behavior depends entirely on your Service Mesh implementation.

The following list outlines the specific implementation details and channel limitations that apply to GRPCRoute resources on OpenShift Container Platform.

Experimental fields
Because OpenShift Container Platform uses the standard-channel CRD, upstream experimental features are not available. For example, the sessionPersistence block is excluded. The CRD will reject configurations that attempt to use any experimental fields.
Rule names
The spec.rules[].name field is currently an experimental feature in the upstream Gateway API. Because OpenShift Container Platform relies on the standard channel, this field is not available. You cannot annotate or deduplicate rule identities, and conformance suites expecting this field might fail.
Match limits
The OpenShift Container Platform schema fully aligns with upstream standard limits. A single GRPCRoute supports up to 16 rules, and each rule supports up to 64 matches. However, the total number of matches across all rules in a single route cannot exceed 128.

3.7. Verify Gateway infrastructure status

To ensure your gateway infrastructure is properly configured and functioning, review the status conditions of your GatewayClass and Gateway custom resources (CRs). Checking these conditions confirms that the controller has successfully programmed your underlying data plane without routing conflicts.

To verify that your gateway infrastructure is functioning correctly, complete the following tasks:

  • Understand GatewayClass status conditions to verify that the controller has claimed the class and that your installed API version is compatible.
  • Review Gateway CR and listener status conditions to pinpoint data plane failures, configuration errors, or negative polarity conflicts.
  • Query gateway infrastructure status using the CLI to quickly validate your deployment and retrieve assigned IP addresses.

3.7.1. GatewayClass status conditions reference

To verify that your GatewayClass custom resource (CR) is valid and ready to provision gateways, review its status conditions. A healthy GatewayClass CR reports a status of True for core conditions like Accepted and SupportedVersion.

Expand
Table 3.4. GatewayClass CR status conditions
ConditionStatusDescription and common reasons

Accepted

True

The GatewayClass CR is valid and the controller has claimed it.

Accepted

False

The configuration has errors or was rejected. Common reasons include InvalidParameters (referenced parameters are invalid or not found), Pending (the controller has not processed the resource yet), or Unknown (an unsupported controllerName was provided).

Accepted

Unknown

The GatewayClass CR is waiting for the controller to process it.

SupportedVersion

True

The installed Gateway API version is compatible with the controller.

SupportedVersion

False

There is a version mismatch. A common reason is UnsupportedVersion, which indicates that the custom resource definition (CRD) version does not match the controller requirements.

ControllerInstalled

True

The Cluster Ingress Operator successfully installed the Gateway API controller.

ControllerInstalled

False

The installation failed.

ControllerInstalled

Unknown

The controller has not started the installation yet.

CRDsReady

True

The Istio CRDs are installed and actively managed by either the Cluster Ingress Operator or OLM.

CRDsReady

False

The CRDs were installed by a third party or have mixed ownership, preventing the controller from managing them.

CRDsReady

Unknown

The CRDs are not installed yet.

To verify that your gateway is configured in the data plane and ready to route traffic, review its gateway-level and listener-level status conditions. A healthy Gateway custom resource (CR) reports a status of True for its Accepted and Programmed conditions.

Important

The Conflicted listener condition uses negative polarity. This means that a status of False indicates a healthy state, while a status of True indicates an error.

Expand
Table 3.5. Gateway-level status conditions
ConditionStatusDescription and common reasons

Accepted

True

The gateway configuration is valid and working properly.

Accepted

False

The configuration has errors. Common reasons include ListenersNotValid (one or more listeners have issues) or InvalidParameters (the configuration is invalid).

Accepted

Unknown

The controller has not evaluated the gateway yet.

Programmed

True

The infrastructure is provisioned and the gateway is configured in the data plane, such as a load balancer or proxy.

Programmed

False

Programming failed or the data plane is not ready. Common reasons include NoResources (insufficient resources or pods unavailable), Invalid (cannot apply to the data plane), or Pending.

Programmed

Unknown

Programming is currently in progress.

LoadBalancerReady

True

The cloud load balancer service for the gateway is successfully provisioned.

LoadBalancerReady

False

The load balancer service failed to provision or is pending. Common reasons include ServiceNotFound, LoadBalancerPending, or SyncLoadBalancerFailed.

DNSReady

True

DNS records for all listeners are functioning correctly.

DNSReady

False

One or more listeners have DNS provisioning issues.

Expand
Table 3.6. Listener-level status conditions
ConditionStatusDescription and common reasons

Accepted

True

The listener configuration is valid and working properly.

Accepted

False

The listener configuration has errors.

Programmed

True

The listener is successfully configured in the data plane.

Programmed

False

The listener configuration failed in the data plane.

ResolvedRefs

True

All references, such as TLS certificates, are found and valid.

ResolvedRefs

False

At least one reference is invalid. Common reasons include InvalidCertificateRef (a TLS certificate was not found or is invalid) or RefNotPermitted (a cross-namespace reference is not allowed).

Conflicted (Negative polarity)

False

Healthy state. There are no conflicts.

Conflicted (Negative polarity)

True

The listener conflicts with another listener. Common reasons include ProtocolConflict (multiple listeners on the same port with incompatible protocols) or HostnameConflict (overlapping hostnames).

DNSReady

True

The DNS record for this listener’s hostname is successfully provisioned in all reported zones.

DNSReady

False

The DNS record failed to provision. Common reasons include FailedZones, NoDNSZones, or RecordNotFound.

DNSReady

Unknown

The DNS status cannot be determined or is unmanaged.

Note

Listeners without a configured hostname will not have DNS conditions added to their status.

Example Gateway CR status output showing a DNS failure on one listener

# ...
status:
  # Gateway-level conditions (LoadBalancer and aggregate DNS status)
  conditions:
  - type: LoadBalancerReady
    status: "True"
    reason: LoadBalancerProvisioned
    message: "The LoadBalancer service is provisioned"
    observedGeneration: 1
    lastTransitionTime: "2025-01-12T10:00:00Z"
  - type: DNSReady
    status: "False"
    reason: SomeListenersNotReady
    message: "One or more listeners have DNS provisioning issues"
    observedGeneration: 1
    lastTransitionTime: "2025-01-12T10:00:00Z"

  # Listener-level conditions (DNS status per listener)
  listeners:
  - name: <stage_http>
    conditions:
    - type: DNSReady
      status: "True"
      reason: NoFailedZones
      message: "The record is provisioned in all reported zones."
      observedGeneration: 1
      lastTransitionTime: "2025-01-12T10:00:00Z"
  - name: <prod_https>
    conditions:
    - type: DNSReady
      status: "False"
      reason: FailedZones
      message: "The record failed to provision in some zones: [<prod.example.com>]"
      observedGeneration: 1
      lastTransitionTime: "2025-01-12T10:00:00Z"

Note

For Google Cloud installations, you can use a custom DNS solution. You must manually create a DNS record for any gateways in Gateway API. For more information, see "Installing a cluster on Google Cloud with customizations".

To quickly check the health of your gateway infrastructure, query specific status fields using the OpenShift Container Platform CLI. You can validate your deployment, check route attachments, and retrieve IP addresses without parsing lengthy YAML manifests.

Prerequisites

  • You have access to the cluster as a user with the cluster-admin role.
  • You have installed the OpenShift CLI (oc).
  • Your gateway is deployed in the openshift-ingress namespace.
  • Your gateway is managed by the gateway controller (openshift.io/gateway-controller/v1).

Procedure

  • Run the relevant command for the status information you need to retrieve:

    • To list all GatewayClass custom resources (CRs) in your cluster, run the following command:

      $ oc get gatewayclass
    • To check if a specific GatewayClass CR has been accepted by the controller, run the following command:

      $ oc get gatewayclass <gatewayclass_name> -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}'
      • <gatewayclass_name>: Specify the name of your gateway class.
    • To list all Gateway custom resources (CRs) across all namespaces, run the following command:

      $ oc get gateway -A
    • To check if a specific Gateway CR is successfully programmed in the data plane, run the following command:

      $ oc get gateway <gateway_name> -n openshift-ingress -o jsonpath='{.status.conditions[?(@.type=="Programmed")].status}'
      • <gateway_name>: Specify the name of your gateway.
    • To retrieve the IP address assigned to a specific Gateway CR, run the following command:

      $ oc get gateway <gateway_name> -n openshift-ingress -o jsonpath='{.status.addresses[0].value}'
      • <gateway_name>: Specify the name of your gateway.
    • To check the total number of routes attached to a specific Gateway CR, run the following command:

      $ oc get gateway <gateway_name> -n openshift-ingress -o jsonpath='{.status.listeners[*].attachedRoutes}'
      • <gateway_name>: Specify the name of your gateway.
    • To watch a specific Gateway CR for real-time status changes, run the following command:

      $ oc get gateway <gateway_name> -n openshift-ingress -w
      • <gateway_name>: Specify the name of your gateway.
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top