Gateway API with OpenShift Container Platform networking
To manage complex network traffic and implement advanced routing policies in OpenShift Container Platform, use the Ingress Operator to configure the Gateway API.
Important
Gateway API does not support user-defined networks (UDN).
Overview of Gateway API
To optimize network traffic management and implement routing policies in OpenShift Container Platform, use the 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 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 API custom resource definitions (CRDs). For OpenShift Container Platform 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
Gatewayobjects that share a common configuration and behavior. For example, two separateGatewayClassobjects might be created to distinguish a set ofGatewayresources 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 OpenShift Container Platform, 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 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 as HAProxy, the
Gatewayobjects 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
GatewayClassresources, cluster administrators might focus on configuringGatewayresources, and application developers might focus on routing their services withHTTPRouteresources. -
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 OpenShift Container Platform
To ensure interoperability between external vendor implementations and your networking infrastructure in OpenShift Container Platform, use the Ingress Operator to manage the lifecycle of Gateway API custom resource definitions (CRDs).
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.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 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.
Getting started with Gateway API for the Ingress Operator
To implement routing policies in your OpenShift Container Platform cluster, create a GatewayClass resource. This resource initializes the Gateway API infrastructure, providing the foundational template required to define and manage how external traffic reaches your internal services.
Important
The OpenShift Container Platform Gateway API implementation relies on the Cluster Ingress Operator (CIO) to install and manage a specific version of OpenShift Service Mesh (OSSM v3.x) in the openshift-ingress namespace.
A conflict occurs if your cluster already has an active OpenShift Service Mesh (OSSM v2.x) subscription in any namespace. OSSM v2.x and OSSM v3.x cannot coexist on the same cluster.
If a conflicting OSSM v2.x subscription is present when you create a GatewayClass resource, the Cluster Ingress Operator attempts to install the required OSSM v3.x components but fails this installation operation. As a result, Gateway API resources, such as Gateway or HTTPRoute, have no effect and no proxy gets configured to route traffic. In OpenShift Container Platform 4.19, this failure is silent. For OpenShift Container Platform 4.20 and later, this conflict causes the ingress ClusterOperator to report a Degraded status.
Before enabling Gateway API by creating a GatewayClass, verify that you do not have an active OSSM v2.x subscription on the cluster.
-
Create a
GatewayClassobject:-
Create a YAML file,
openshift-default.yaml, that contains the following information:ExampleGatewayClassCRapiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: openshift-default spec: controllerName: openshift.io/gateway-controller/v1-
controllerName: The controller name.Important
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
GatewayClassobject and all associatedGateway,GRPCRoute, andHTTPRouteobjects. The controller name is tied to the implementation of Gateway API in OpenShift Container Platform, andopenshift.io/gateway-controller/v1is the only controller name allowed.
-
-
Run the following command to create the
GatewayClassresource:$ oc create -f openshift-default.yamlExample outputgatewayclass.gateway.networking.k8s.io/openshift-default createdDuring the creation of the
GatewayClassresource, the Ingress Operator installs a lightweight version of Red Hat OpenShift Service Mesh, an Istio custom resource, and a new deployment in theopenshift-ingressnamespace. -
Optional: Verify that the new deployment,
istiod-openshift-gateway, is ready and available:$ oc get deployment -n openshift-ingressExample outputNAME READY UP-TO-DATE AVAILABLE AGE istiod-openshift-gateway 1/1 1 1 55s router-default 2/2 2 2 6h4m
-
-
Create a secret by running the following command:
$ oc -n openshift-ingress create secret tls gwapi-wildcard --cert=wildcard.crt --key=wildcard.key -
Get the domain of the Ingress Operator by running the following command:
$ DOMAIN=$(oc get ingresses.config/cluster -o jsonpath={.spec.domain}) -
Create a
Gatewayobject:-
Create a YAML file,
example-gateway.yaml, that contains the following information:ExampleGatewayCRapiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: example-gateway namespace: openshift-ingress spec: gatewayClassName: openshift-default listeners: - name: https hostname: "*.gwapi.${DOMAIN}" port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: gwapi-wildcard allowedRoutes: namespaces: from: Allwhere:
metadata.namespace-
The
Gatewayobject must be created in theopenshift-ingressnamespace. gatewayClassName-
The
Gatewayobject must reference the name of the previously createdGatewayClassobject. listeners.name-
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
HTTPRouteresources. listeners.hostname-
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.
tls.name-
The name of the previously created secret.
-
Apply the resource by running the following command:
$ oc apply -f example-gateway.yaml -
Optional: When you create a
Gatewayobject, 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-defaultExample outputNAME 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-defaultExample outputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-gateway-openshift-default LoadBalancer 10.1.2.3 <external_ipname> <port_info> 47s
-
-
Optional: The Ingress Operator automatically creates a
DNSRecordCR using the hostname from the listeners, and adds the labelgateway.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 yamlExample outputkind: 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: ...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 "Enabling a user-managed DNS" and "Provisioning your own DNS records".
-
-
Create an
HTTPRouteresource that directs requests to your already-created namespace and application calledexample-app/example-app:-
Create a YAML file,
example-route.yaml, that contains the following information:ExampleHTTPRouteCRapiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: example-route namespace: example-app-ns spec: parentRefs: - name: example-gateway namespace: openshift-ingress hostnames: ["example.gwapi.${DOMAIN}"] rules: - backendRefs: - name: example-app port: 8443where:
metadata.namespace-
The namespace you are deploying your application.
spec.parentRefs-
This field must point to the
Gatewayobject you previously configured. spec.hostnames-
The hostname must match the one specified in the
Gatewayobject. In this case, the listeners use a wildcard hostname. rules.backendRefs-
This field specifies the backend references that point to your service.
rules.name-
The name of the
Servicefor your application.
-
Apply the resource by running the following command:
$ oc apply -f example-route.yamlExample outputhttproute.gateway.networking.k8s.io/example-route created
-
-
Verify that the
Gatewayobject is deployed and has the conditionProgrammedby running the following command:$ oc wait -n openshift-ingress --for=condition=Programmed gateways.gateway.networking.k8s.io example-gatewayExample outputgateway.gateway.networking.k8s.io/example-gateway condition met -
Send a request to the configured
HTTPRouteobject hostname:$ curl -I --cacert <local cert file> https://example.gwapi.${DOMAIN}:443
Gateway API deployment topologies
To optimise network security and resource allocation in OpenShift Container Platform, choose between shared or dedicated gateway topologies when implementing the Gateway API. Selecting the appropriate topology ensures your infrastructure meets specific security requirements and operational advantages for your workloads.
- Dedicated gateway
-
Routes and any load balancers or proxies are served from the same namespace. The
Gatewayobject 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:
Gateway resourceapiVersion: 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"
-
spec.listeneres:: If you do not setspec.listeners[].allowedRoutesfor aGatewayresource, the system implicitly sets thenamespaces.fromfield to the value ofSame.
The following example shows the associated HTTPRoute resource, sales-db, which attaches to the dedicated Gateway object:
HTTPRoute resourceapiVersion: 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. The system implicitly assumes that the route is exists in the same namespace as the Gateway object.
- Shared gateway
-
Routes are served from multiple namespaces or multiple hostnames. The
Gatewayobject allows routes from application namespaces by using thespec.listeners.allowedRoutes.namespacesfield.
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":
Gateway resourceapiVersion: 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:
Namespace resourcesapiVersion: 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.
Removing conflicts between the Gateway API and the OSSM v2.x
To restore cluster health and resolve operator degradation in OpenShift Container Platform 4.20 and later, identify and remove conflicts between the Gateway API and OpenShift Service Mesh (OSSM) v2.x. Ensuring these subscriptions do not overlap allows the ingress Cluster Operator to maintain a healthy status when you create a GatewayClass resource.
The conflict occurs because the Gateway API implementation requires OSSM v3.x, which cannot coexist with OSSM v2.x. The CIO detects this conflict, stops the Gateway API provisioning, and reports the Degraded status to alert administrators.
Your Cluster Operator reports a status of True and a type of Degraded with a reason of GatewayAPIOSSMConflict. Verify by running the following command:
$ oc get clusteroperator ingress -o yaml
In the status section of the output, look for a Degraded condition with status: "True" and reason: GatewayAPIOSSMConflict.
status:
conditions:
lastTransitionTime: "2025-10-22T17:00:00Z"
message: 'Failed to install OpenShift Service Mesh 3.x for Gateway API: A
conflicting OpenShift Service Mesh 2.x subscription was found. Remove the
GatewayClass resource or the conflicting OSSM 2.x subscription to resolve.'
reason: GatewayAPIOSSMConflict
status: "True"
type: Degraded
You can resolve this issue and clear the Degraded status either by removing the GatewayClass resource or by using OpenShift Gateway API to remove the conflicting OpenShift Service Mesh v2.x subscription from the cluster.
-
If you do not intend to use the OpenShift Gateway API, remove the
GatewayClassresource. This signals to the Ingress Operator to stop attempting to provision Gateway API.$ oc delete gatewayclass <gatewayclass-name> -
If you do intend to use the OpenShift Gateway API, you must remove the conflicting OpenShift Service Mesh v2.x subscription from the cluster.
$ oc -n openshift-operators delete subscription <OSSM v2.x subscription name>After you remove the v2.x subscription, the Ingress Operator automatically retries the installation of OSSM v3.x and completes the Gateway API provisioning.