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.
Traffic delivery can be configured for an HTTPRoute using rules. 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.
Creating a basic HTTPRoute custom resource¶
To direct incoming network traffic from a gateway to your backend applications, you must create an HTTPRoute custom resource (CR). The resource specifies the hostnames the route handles and binds them to a parent Gateway CR.
Prerequisites
- You created a target backend service.
- You know the name and namespace of the parent
GatewayCR.
Procedure
-
Create an
HTTPRouteCR file that references your parent gateway, application hostnames, and backend service, and save it ashttproute.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: sample-route namespace: my-application spec: parentRefs: - name: generic-gateway namespace: openshift-ingress hostnames: - app1.example.com - app2.example.com rules: - backendRefs: - name: application-backend port: 8080- You must include application hostnames and a
backendRefrule that points to your backend service. - If your
HTTPRouteandGatewayCRs are deployed in different namespaces, theGatewayCR listener must allow routes from theHTTPRoutenamespace. You must configure thespec.listeners.allowedRoutes.namespacesfield in theGatewayCR and specify a selector for trusted namespaces. - The listener
hostnameon the parentGatewayCR should cover the hostnames in yourHTTPRouteCR. For example, a listener hostname of*.gwapi.apps.example.comaccepts anHTTPRoutehostname such asapp.gwapi.apps.example.com, but rejects hostnames outside that domain.
- You must include application hostnames and a
-
Apply the
HTTPRouteCR file to your cluster:
Verification
-
Verify that the
HTTPRouteCR was successfully created:
Configuring path-based routing¶
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 installed the OpenShift CLI (
oc).
Procedure
-
Create or edit an
HTTPRouteYAML file to include your desired match conditions under thespec.rules.matchesfield. The following example demonstrates a completeHTTPRoutecustom 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 supported-httproute-match-types_routing-http-requests-to-services.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 -
Apply the
HTTPRouteCR by running the following command:
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.
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
pathspecifies that the request must match a specific URL path.type: Exactensures the route only matches the exact string/<example_app>.backendRefsdefines the service where matching traffic is sent.
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
Applying 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 installed the OpenShift CLI (
oc).
Procedure
-
Create or edit an
HTTPRouteYAML file to include your desired processing directives under thespec.rules.filtersfield. The following example demonstrates a completeHTTPRoutecustom resource (CR) with arequestRedirectfilter that issues a permanent redirect (301) from HTTP to HTTPS. For details on configuring other filter types, see supported-httproute-filters_routing-http-requests-to-services.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 -
Apply the
HTTPRouteCR by running the following command:
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).
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
hostnamesdefines the domain, such as"<example.com>", that this route applies to.filtersspecifies the processing logic. In this example, theRequestRedirecttype is used.scheme: httpsinstructs the gateway to redirect the client to the secure version of the URL.statusCode: 301indicates a permanent redirect.
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"]
Configuring routing destinations and traffic weights¶
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 installed the OpenShift CLI (
oc).
Procedure
-
Create or edit an
HTTPRouteYAML file to include your desired service destinations under thespec.rules.backendRefsfield. The following example demonstrates a completeHTTPRoutecustom 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 httproute-backendref-configuration_routing-http-requests-to-services. -
Apply the
HTTPRouteCR by running the following command:
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.
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
backendRefsdefines the destination services for the traffic.namespecifies the name of the Kubernetes service.portspecifies the port on which the service is listening.
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
Setting 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 installed the OpenShift CLI (
oc).
Procedure
-
Create or edit an
HTTPRouteYAML file to include your desired timeout configurations under thespec.rules.timeoutsfield. The following example demonstrates a completeHTTPRoutecustom resource (CR) where the entire request must complete within 30 seconds. For details on timeout formatting rules and backend request timeouts, see httproute-timeout-configuration_routing-http-requests-to-services.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 -
Apply the
HTTPRouteCR by running the following command:
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
backendRequesttimeout cannot be greater than the value of therequesttimeout. - If specified, a timeout value must be
0or greater than or equal to1ms. - 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.
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
requestspecifies the timeout for the full request-response cycle.PathPrefixensures 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
OpenShift Container Platform routes and HTTPRoutes comparison¶
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:
Shared features and implementation differences
| Feature | OpenShift Container Platform route implementation | HTTPRoute 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). |