- Route configuration
- Creating an HTTP-based route
- Creating a route for Ingress Controller sharding
- Configuring route timeouts
- HTTP Strict Transport Security
- Throughput issue troubleshooting methods
- Using cookies to keep route statefulness
- Path-based routes
- Route-specific annotations
- Configuring the route admission policy
- Creating a route through an Ingress object
- Creating a route using the destination CA certificate in the Ingress annotation
- Configuring the OKD Ingress Controller for dual-stack networking
Route configuration
Creating an HTTP-based route
A route allows you to host your application at a public URL. It can either be secure or unsecured, depending on the network security configuration of your application. An HTTP-based route is an unsecured route that uses the basic HTTP routing protocol and exposes a service on an unsecured application port.
The following procedure describes how to create a simple HTTP-based route to a web application, using the hello-openshift
application as an example.
Prerequisites
You installed the OpenShift CLI (
oc
).You are logged in as an administrator.
You have a web application that exposes a port and a TCP endpoint listening for traffic on the port.
Procedure
Create a project called
hello-openshift
by running the following command:$ oc new-project hello-openshift
Create a pod in the project by running the following command:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
Create a service called
hello-openshift
by running the following command:$ oc expose pod/hello-openshift
Create an unsecured route to the
hello-openshift
application by running the following command:$ oc expose svc hello-openshift
If you examine the resulting
Route
resource, it should look similar to the following:YAML definition of the created unsecured route:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: hello-openshift
spec:
host: hello-openshift-hello-openshift.<Ingress_Domain> (1)
port:
targetPort: 8080
to:
kind: Service
name: hello-openshift
1 <Ingress_Domain>
is the default ingress domain name.To display your default ingress domain, run the following command:
$ oc get ingresses.config/cluster -o jsonpath={.spec.domain}
Creating a route for Ingress Controller sharding
A route allows you to host your application at a URL. In this case, the hostname is not set and the route uses a subdomain instead. When you specify a subdomain, you automatically use the domain of the Ingress Controller that exposes the route. For situations where a route is exposed by multiple Ingress Controllers, the route is hosted at multiple URLs.
The following procedure describes how to create a route for Ingress Controller sharding, using the hello-openshift
application as an example.
Ingress Controller sharding is useful when balancing incoming traffic load among a set of Ingress Controllers and when isolating traffic to a specific Ingress Controller. For example, company A goes to one Ingress Controller and company B to another.
Prerequisites
You installed the OpenShift CLI (
oc
).You are logged in as a project administrator.
You have a web application that exposes a port and an HTTP or TLS endpoint listening for traffic on the port.
You have configured the Ingress Controller for sharding.
Procedure
Create a project called
hello-openshift
by running the following command:$ oc new-project hello-openshift
Create a pod in the project by running the following command:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
Create a service called
hello-openshift
by running the following command:$ oc expose pod/hello-openshift
Create a route definition called
hello-openshift-route.yaml
:YAML definition of the created route for sharding:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
type: sharded (1)
name: hello-openshift-edge
namespace: hello-openshift
spec:
subdomain: hello-openshift (2)
tls:
termination: edge
to:
kind: Service
name: hello-openshift
1 Both the label key and its corresponding label value must match the ones specified in the Ingress Controller. In this example, the Ingress Controller has the label key and value type: sharded
.2 The route will be exposed using the value of the subdomain
field. When you specify thesubdomain
field, you must leave the hostname unset. If you specify both thehost
andsubdomain
fields, then the route will use the value of thehost
field, and ignore thesubdomain
field.Use
hello-openshift-route.yaml
to create a route to thehello-openshift
application by running the following command:$ oc -n hello-openshift create -f hello-openshift-route.yaml
Verification
Get the status of the route with the following command:
$ oc -n hello-openshift get routes/hello-openshift-edge -o yaml
The resulting
Route
resource should look similar to the following:Example output
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
type: sharded
name: hello-openshift-edge
namespace: hello-openshift
spec:
subdomain: hello-openshift
tls:
termination: edge
to:
kind: Service
name: hello-openshift
status:
ingress:
- host: hello-openshift.<apps-sharded.basedomain.example.net> (1)
routerCanonicalHostname: router-sharded.<apps-sharded.basedomain.example.net> (2)
routerName: sharded (3)
1 The hostname the Ingress Controller, or router, uses to expose the route. The value of the host
field is automatically determined by the Ingress Controller, and uses its domain. In this example, the domain of the Ingress Controller is<apps-sharded.basedomain.example.net>
.2 The hostname of the Ingress Controller. 3 The name of the Ingress Controller. In this example, the Ingress Controller has the name sharded
.
Configuring route timeouts
You can configure the default timeouts for an existing route when you have services in need of a low timeout, which is required for Service Level Availability (SLA) purposes, or a high timeout, for cases with a slow back end.
Prerequisites
- You need a deployed Ingress Controller on a running cluster.
Procedure
Using the
oc annotate
command, add the timeout to the route:$ oc annotate route <route_name> \
--overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit> (1)
1 Supported time units are microseconds (us), milliseconds (ms), seconds (s), minutes (m), hours (h), or days (d). The following example sets a timeout of two seconds on a route named
myroute
:$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
HTTP Strict Transport Security
HTTP Strict Transport Security (HSTS) policy is a security enhancement, which signals to the browser client that only HTTPS traffic is allowed on the route host. HSTS also optimizes web traffic by signaling HTTPS transport is required, without using HTTP redirects. HSTS is useful for speeding up interactions with websites.
When HSTS policy is enforced, HSTS adds a Strict Transport Security header to HTTP and HTTPS responses from the site. You can use the insecureEdgeTerminationPolicy
value in a route to redirect HTTP to HTTPS. When HSTS is enforced, the client changes all requests from the HTTP URL to HTTPS before the request is sent, eliminating the need for a redirect.
Cluster administrators can configure HSTS to do the following:
Enable HSTS per-route
Disable HSTS per-route
Enforce HSTS per-domain, for a set of domains, or use namespace labels in combination with domains
HSTS works only with secure routes, either edge-terminated or re-encrypt. The configuration is ineffective on HTTP or passthrough routes. |
Enabling HTTP Strict Transport Security per-route
HTTP strict transport security (HSTS) is implemented in the HAProxy template and applied to edge and re-encrypt routes that have the haproxy.router.openshift.io/hsts_header
annotation.
Prerequisites
You are logged in to the cluster with a user with administrator privileges for the project.
You installed the
oc
CLI.
Procedure
To enable HSTS on a route, add the
haproxy.router.openshift.io/hsts_header
value to the edge-terminated or re-encrypt route:Example route configured with an annotation
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload (1) (2) (3)
...
spec:
host: def.abc.com
tls:
termination: "reencrypt"
...
wildcardPolicy: "Subdomain"
1 Required. max-age
measures the length of time, in seconds, that the HSTS policy is in effect. If set to0
, it negates the policy.2 Optional. When included, includeSubDomains
tells the client that all subdomains of the host must have the same HSTS policy as the host.3 Optional. When max-age
is greater than 0, you can addpreload
inhaproxy.router.openshift.io/hsts_header
to allow external services to include this site in their HSTS preload lists. For example, sites such as Google can construct a list of sites that havepreload
set. Browsers can then use these lists to determine which sites they can communicate with over HTTPS, even before they have interacted with the site. Withoutpreload
set, browsers must have interacted with the site over HTTPS, at least once, to get the header.
Disabling HTTP Strict Transport Security per-route
To disable HTTP strict transport security (HSTS) per-route, you can set the max-age
value in the route annotation to 0
.
Prerequisites
You are logged in to the cluster with a user with administrator privileges for the project.
You installed the
oc
CLI.
Procedure
To disable HSTS, set the
max-age
value in the route annotation to0
, by entering the following command:$ oc annotate route <rout_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
You can alternatively apply the following YAML to create the config map:
Example of disabling HSTS per-routemetadata:
annotations:
haproxy.router.openshift.io/hsts_header: max-age=0
To disable HSTS for every route in a namespace, enter the followinf command:
$ oc annotate <route> --all -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
Verification
To query the annotation for all routes, enter the following command:
$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}'
Example output
Name: routename HSTS: max-age=0
Enforcing HTTP Strict Transport Security per-domain
To enforce HTTP Strict Transport Security (HSTS) per-domain for secure routes, add a requiredHSTSPolicies
record to the Ingress spec to capture the configuration of the HSTS policy.
If you configure a requiredHSTSPolicy
to enforce HSTS, then any newly created route must be configured with a compliant HSTS policy annotation.
To handle upgraded clusters with non-compliant HSTS routes, you can update the manifests at the source and apply the updates. |
You cannot use |
HSTS cannot be applied to insecure, or non-TLS routes, even if HSTS is requested for all routes globally. |
Prerequisites
You are logged in to the cluster with a user with administrator privileges for the project.
You installed the
oc
CLI.
Procedure
Edit the Ingress config file:
$ oc edit ingresses.config.openshift.io/cluster
Example HSTS policy
apiVersion: config.openshift.io/v1
kind: Ingress
metadata:
name: cluster
spec:
domain: 'hello-openshift-default.apps.username.devcluster.openshift.com'
requiredHSTSPolicies: (1)
- domainPatterns: (2)
- '*hello-openshift-default.apps.username.devcluster.openshift.com'
- '*hello-openshift-default2.apps.username.devcluster.openshift.com'
namespaceSelector: (3)
matchLabels:
myPolicy: strict
maxAge: (4)
smallestMaxAge: 1
largestMaxAge: 31536000
preloadPolicy: RequirePreload (5)
includeSubDomainsPolicy: RequireIncludeSubDomains (6)
- domainPatterns: (2)
- 'abc.example.com'
- '*xyz.example.com'
namespaceSelector:
matchLabels: {}
maxAge: {}
preloadPolicy: NoOpinion
includeSubDomainsPolicy: RequireNoIncludeSubDomains
1 Required. requiredHSTSPolicies
are validated in order, and the first matchingdomainPatterns
applies.2 Required. You must specify at least one domainPatterns
hostname. Any number of domains can be listed. You can include multiple sections of enforcing options for differentdomainPatterns
.3 Optional. If you include namespaceSelector
, it must match the labels of the project where the routes reside, to enforce the set HSTS policy on the routes. Routes that only match thenamespaceSelector
and not thedomainPatterns
are not validated.4 Required. max-age
measures the length of time, in seconds, that the HSTS policy is in effect. This policy setting allows for a smallest and largestmax-age
to be enforced.The
largestMaxAge
value must be between0
and2147483647
. It can be left unspecified, which means no upper limit is enforced.The
smallestMaxAge
value must be between0
and2147483647
. Enter0
to disable HSTS for troubleshooting, otherwise enter1
if you never want HSTS to be disabled. It can be left unspecified, which means no lower limit is enforced.
5 Optional. Including preload
inhaproxy.router.openshift.io/hsts_header
allows external services to include this site in their HSTS preload lists. Browsers can then use these lists to determine which sites they can communicate with over HTTPS, before they have interacted with the site. Withoutpreload
set, browsers need to interact at least once with the site to get the header.preload
can be set with one of the following:RequirePreload
:preload
is required by theRequiredHSTSPolicy
.RequireNoPreload
:preload
is forbidden by theRequiredHSTSPolicy
.NoOpinion
:preload
does not matter to theRequiredHSTSPolicy
.
6 Optional. includeSubDomainsPolicy
can be set with one of the following:RequireIncludeSubDomains
:includeSubDomains
is required by theRequiredHSTSPolicy
.RequireNoIncludeSubDomains
:includeSubDomains
is forbidden by theRequiredHSTSPolicy
.NoOpinion
:includeSubDomains
does not matter to theRequiredHSTSPolicy
.
You can apply HSTS to all routes in the cluster or in a particular namespace by entering the
oc annotate command
.To apply HSTS to all routes in the cluster, enter the
oc annotate command
. For example:$ oc annotate route --all --all-namespaces --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000"
To apply HSTS to all routes in a particular namespace, enter the
oc annotate command
. For example:$ oc annotate route --all -n my-namespace --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000"
Verification
You can review the HSTS policy you configured. For example:
To review the
maxAge
set for required HSTS policies, enter the following command:$ oc get clusteroperator/ingress -n openshift-ingress-operator -o jsonpath='{range .spec.requiredHSTSPolicies[*]}{.spec.requiredHSTSPolicies.maxAgePolicy.largestMaxAge}{"\n"}{end}'
To review the HSTS annotations on all routes, enter the following command:
$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}'
Example output
Name: <_routename_> HSTS: max-age=31536000;preload;includeSubDomains
Throughput issue troubleshooting methods
Sometimes applications deployed by using OKD can cause network throughput issues, such as unusually high latency between specific services.
If pod logs do not reveal any cause of the problem, use the following methods to analyze performance issues:
Use a packet analyzer, such as
ping
ortcpdump
to analyze traffic between a pod and its node.For example, run the tcpdump tool on each pod while reproducing the behavior that led to the issue. Review the captures on both sides to compare send and receive timestamps to analyze the latency of traffic to and from a pod. Latency can occur in OKD if a node interface is overloaded with traffic from other pods, storage devices, or the data plane.
$ tcpdump -s 0 -i any -w /tmp/dump.pcap host <podip 1> && host <podip 2> (1)
1 podip
is the IP address for the pod. Run theoc get pod <pod_name> -o wide
command to get the IP address of a pod.The
tcpdump
command generates a file at/tmp/dump.pcap
containing all traffic between these two pods. You can run the analyzer shortly before the issue is reproduced and stop the analyzer shortly after the issue is finished reproducing to minimize the size of the file. You can also run a packet analyzer between the nodes (eliminating the SDN from the equation) with:$ tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789
Use a bandwidth measuring tool, such as iperf, to measure streaming throughput and UDP throughput. Locate any bottlenecks by running the tool from the pods first, and then running it from the nodes.
In some cases, the cluster may mark the node with the router pod as unhealthy due to latency issues. Use worker latency profiles to adjust the frequency that the cluster waits for a status update from the node before taking action.
If your cluster has designated lower-latency and higher-latency nodes, configure the
spec.nodePlacement
field in the Ingress Controller to control the placement of the router pod.
Additional resources
Using cookies to keep route statefulness
OKD provides sticky sessions, which enables stateful application traffic by ensuring all traffic hits the same endpoint. However, if the endpoint pod terminates, whether through restart, scaling, or a change in configuration, this statefulness can disappear.
OKD can use cookies to configure session persistence. The Ingress controller selects an endpoint to handle any user requests, and creates a cookie for the session. The cookie is passed back in the response to the request and the user sends the cookie back with the next request in the session. The cookie tells the Ingress Controller which endpoint is handling the session, ensuring that client requests use the cookie so that they are routed to the same pod.
Cookies cannot be set on passthrough routes, because the HTTP traffic cannot be seen. Instead, a number is calculated based on the source IP address, which determines the backend. If backends change, the traffic can be directed to the wrong server, making it less sticky. If you are using a load balancer, which hides source IP, the same number is set for all connections and traffic is sent to the same pod. |
Annotating a route with a cookie
You can set a cookie name to overwrite the default, auto-generated one for the route. This allows the application receiving route traffic to know the cookie name. By deleting the cookie it can force the next request to re-choose an endpoint. So, if a server was overloaded it tries to remove the requests from the client and redistribute them.
Procedure
Annotate the route with the specified cookie name:
$ oc annotate route <route_name> router.openshift.io/cookie_name="<cookie_name>"
where:
<route_name>
Specifies the name of the route.
<cookie_name>
Specifies the name for the cookie.
For example, to annotate the route
my_route
with the cookie namemy_cookie
:$ oc annotate route my_route router.openshift.io/cookie_name="my_cookie"
Capture the route hostname in a variable:
$ ROUTE_NAME=$(oc get route <route_name> -o jsonpath='{.spec.host}')
where:
<route_name>
Specifies the name of the route.
Save the cookie, and then access the route:
$ curl $ROUTE_NAME -k -c /tmp/cookie_jar
Use the cookie saved by the previous command when connecting to the route:
$ curl $ROUTE_NAME -k -b /tmp/cookie_jar
Path-based routes
Path-based routes specify a path component that can be compared against a URL, which requires that the traffic for the route be HTTP based. Thus, multiple routes can be served using the same hostname, each with a different path. Routers should match routes based on the most specific path to the least. However, this depends on the router implementation.
The following table shows example routes and their accessibility:
Route | When Compared to | Accessible |
---|---|---|
www.example.com/test | www.example.com/test | Yes |
www.example.com | No | |
www.example.com/test and www.example.com | www.example.com/test | Yes |
www.example.com | Yes | |
www.example.com | www.example.com/text | Yes (Matched by the host, not the route) |
www.example.com | Yes |
An unsecured route with a path
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: route-unsecured
spec:
host: www.example.com
path: "/test" (1)
to:
kind: Service
name: service-name
1 | The path is the only added attribute for a path-based route. |
Path-based routing is not available when using passthrough TLS, as the router does not terminate TLS in that case and cannot read the contents of the request. |
Route-specific annotations
The Ingress Controller can set the default options for all the routes it exposes. An individual route can override some of these defaults by providing specific configurations in its annotations. Red Hat does not support adding a route annotation to an operator-managed route.
To create a whitelist with multiple source IPs or subnets, use a space-delimited list. Any other delimiter type causes the list to be ignored without a warning or error message. |
Variable | Description | Environment variable used as default |
---|---|---|
| Sets the load-balancing algorithm. Available options are |
|
| Disables the use of cookies to track related connections. If set to | |
| Specifies an optional cookie to use for this route. The name must consist of any combination of upper and lower case letters, digits, ““, and “-“. The default is the hashed internal key name for the route. | |
| Sets the maximum number of connections that are allowed to a backing pod from a router. | |
| Setting | |
| Limits the number of concurrent TCP connections made through the same source IP address. It accepts a numeric value. | |
| Limits the rate at which a client with the same source IP address can make HTTP requests. It accepts a numeric value. | |
| Limits the rate at which a client with the same source IP address can make TCP connections. It accepts a numeric value. | |
| Sets a server-side timeout for the route. (TimeUnits) |
|
| This timeout applies to a tunnel connection, for example, WebSocket over cleartext, edge, reencrypt, or passthrough routes. With cleartext, edge, or reencrypt route types, this annotation is applied as a timeout tunnel with the existing timeout value. For the passthrough route types, the annotation takes precedence over any existing timeout value set. |
|
| You can set either an IngressController or the ingress config . This annotation redeploys the router and configures the HA proxy to emit the haproxy |
|
| Sets the interval for the back-end health checks. (TimeUnits) |
|
| Sets a whitelist for the route. The whitelist is a space-separated list of IP addresses and CIDR ranges for the approved source addresses. Requests from IP addresses that are not in the whitelist are dropped. The maximum number of IP addresses and CIDR ranges allowed in a whitelist is 61. | |
| Sets a Strict-Transport-Security header for the edge terminated or re-encrypt route. | |
| Sets the | |
| Sets the rewrite path of the request on the backend. | |
| Sets a value to restrict cookies. The values are:
This value is applicable to re-encrypt and edge routes only. For more information, see the SameSite cookies documentation. | |
| Sets the policy for handling the
|
|
Environment variables cannot be edited. |
Router timeout variables
TimeUnits
are represented by a number followed by the unit: us
*(microseconds), ms
(milliseconds, default), s
(seconds), m
(minutes), h
*(hours), d
(days).
The regular expression is: [1-9][0-9]*(us
\|ms
\|s
\|m
\|h
\|d
).
Variable | Default | Description |
---|---|---|
|
| Length of time between subsequent liveness checks on back ends. |
|
| Controls the TCP FIN timeout period for the client connecting to the route. If the FIN sent to close the connection does not answer within the given time, HAProxy closes the connection. This is harmless if set to a low value and uses fewer resources on the router. |
|
| Length of time that a client has to acknowledge or send data. |
|
| The maximum connection time. |
|
| Controls the TCP FIN timeout from the router to the pod backing the route. |
|
| Length of time that a server has to acknowledge or send data. |
|
| Length of time for TCP or WebSocket connections to remain open. This timeout period resets whenever HAProxy reloads. |
|
| Set the maximum time to wait for a new HTTP request to appear. If this is set too low, it can cause problems with browsers and applications not expecting a small Some effective timeout values can be the sum of certain variables, rather than the specific expected timeout. For example, |
|
| Length of time the transmission of an HTTP request can take. |
|
| Allows the minimum frequency for the router to reload and accept new changes. |
|
| Timeout for the gathering of HAProxy metrics. |
A route setting custom timeout
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/timeout: 5500ms (1)
...
1 | Specifies the new timeout with HAProxy supported units (us , ms , s , m , h , d ). If the unit is not provided, ms is the default. |
Setting a server-side timeout value for passthrough routes too low can cause WebSocket connections to timeout frequently on that route. |
A route that allows only one specific IP address
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
A route that allows several IP addresses
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12
A route that allows an IP address CIDR network
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24
A route that allows both IP an address and IP address CIDR networks
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8
A route specifying a rewrite target
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/rewrite-target: / (1)
...
1 | Sets / as rewrite path of the request on the backend. |
Setting the haproxy.router.openshift.io/rewrite-target
annotation on a route specifies that the Ingress Controller should rewrite paths in HTTP requests using this route before forwarding the requests to the backend application. The part of the request path that matches the path specified in spec.path
is replaced with the rewrite target specified in the annotation.
The following table provides examples of the path rewriting behavior for various combinations of spec.path
, request path, and rewrite target.
Route.spec.path | Request path | Rewrite target | Forwarded request path |
---|---|---|---|
/foo | /foo | / | / |
/foo | /foo/ | / | / |
/foo | /foo/bar | / | /bar |
/foo | /foo/bar/ | / | /bar/ |
/foo | /foo | /bar | /bar |
/foo | /foo/ | /bar | /bar/ |
/foo | /foo/bar | /baz | /baz/bar |
/foo | /foo/bar/ | /baz | /baz/bar/ |
/foo/ | /foo | / | N/A (request path does not match route path) |
/foo/ | /foo/ | / | / |
/foo/ | /foo/bar | / | /bar |
Configuring the route admission policy
Administrators and application developers can run applications in multiple namespaces with the same domain name. This is for organizations where multiple teams develop microservices that are exposed on the same hostname.
Allowing claims across namespaces should only be enabled for clusters with trust between namespaces, otherwise a malicious user could take over a hostname. For this reason, the default admission policy disallows hostname claims across namespaces. |
Prerequisites
- Cluster administrator privileges.
Procedure
Edit the
.spec.routeAdmission
field of theingresscontroller
resource variable using the following command:$ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge
Sample Ingress Controller configuration
spec:
routeAdmission:
namespaceOwnership: InterNamespaceAllowed
...
You can alternatively apply the following YAML to configure the route admission policy:
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
name: default
namespace: openshift-ingress-operator
spec:
routeAdmission:
namespaceOwnership: InterNamespaceAllowed
Creating a route through an Ingress object
Some ecosystem components have an integration with Ingress resources but not with route resources. To cover this case, OKD automatically creates managed route objects when an Ingress object is created. These route objects are deleted when the corresponding Ingress objects are deleted.
Procedure
Define an Ingress object in the OKD console or by entering the
oc create
command:YAML Definition of an Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
annotations:
route.openshift.io/termination: "reencrypt" (1)
route.openshift.io/destination-ca-certificate-secret: secret-ca-cert (3)
spec:
rules:
- host: www.example.com (2)
http:
paths:
- backend:
service:
name: frontend
port:
number: 443
path: /
pathType: Prefix
tls:
- hosts:
- www.example.com
secretName: example-com-tls-certificate
1 The route.openshift.io/termination
annotation can be used to configure thespec.tls.termination
field of theRoute
asIngress
has no field for this. The accepted values areedge
,passthrough
andreencrypt
. All other values are silently ignored. When the annotation value is unset,edge
is the default route. The TLS certificate details must be defined in the template file to implement the default edge route.2 When working with an Ingress
object, you must specify an explicit hostname, unlike when working with routes. You can use the<host_name>.<cluster_ingress_domain>
syntax, for exampleapps.openshiftdemos.com
, to take advantage of the*.<cluster_ingress_domain>
wildcard DNS record and serving certificate for the cluster. Otherwise, you must ensure that there is a DNS record for the chosen hostname.If you specify the
passthrough
value in theroute.openshift.io/termination
annotation, setpath
to‘’
andpathType
toImplementationSpecific
in the spec:spec:
rules:
- host: www.example.com
http:
paths:
- path: ‘’
pathType: ImplementationSpecific
backend:
service:
name: frontend
port:
number: 443
$ oc apply -f ingress.yaml
3 The route.openshift.io/destination-ca-certificate-secret
can be used on an Ingress object to define a route with a custom destination certificate (CA). The annotation references a kubernetes secret,secret-ca-cert
that will be inserted into the generated route.To specify a route object with a destination CA from an ingress object, you must create a
kubernetes.io/tls
orOpaque
type secret with a certificate in PEM-encoded format in thedata.tls.crt
specifier of the secret.
List your routes:
$ oc get routes
The result includes an autogenerated route whose name starts with
frontend-
:NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
frontend-gnztq www.example.com frontend 443 reencrypt/Redirect None
If you inspect this route, it looks this:
YAML Definition of an autogenerated route
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: frontend-gnztq
ownerReferences:
- apiVersion: networking.k8s.io/v1
controller: true
kind: Ingress
name: frontend
uid: 4e6c59cc-704d-4f44-b390-617d879033b6
spec:
host: www.example.com
path: /
port:
targetPort: https
tls:
certificate: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
insecureEdgeTerminationPolicy: Redirect
key: |
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
termination: reencrypt
destinationCACertificate: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
to:
kind: Service
name: frontend
Creating a route using the destination CA certificate in the Ingress annotation
The route.openshift.io/destination-ca-certificate-secret
annotation can be used on an Ingress object to define a route with a custom destination CA certificate.
Prerequisites
You may have a certificate/key pair in PEM-encoded files, where the certificate is valid for the route host.
You may have a separate CA certificate in a PEM-encoded file that completes the certificate chain.
You must have a separate destination CA certificate in a PEM-encoded file.
You must have a service that you want to expose.
Procedure
Add the
route.openshift.io/destination-ca-certificate-secret
to the Ingress annotations:apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
annotations:
route.openshift.io/termination: "reencrypt"
route.openshift.io/destination-ca-certificate-secret: secret-ca-cert (1)
...
1 The annotation references a kubernetes secret. The secret referenced in this annotation will be inserted into the generated route.
Example output
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: frontend
annotations:
route.openshift.io/termination: reencrypt
route.openshift.io/destination-ca-certificate-secret: secret-ca-cert
spec:
...
tls:
insecureEdgeTerminationPolicy: Redirect
termination: reencrypt
destinationCACertificate: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
...
Configuring the OKD Ingress Controller for dual-stack networking
If your OKD cluster is configured for IPv4 and IPv6 dual-stack networking, your cluster is externally reachable by OKD routes.
The Ingress Controller automatically serves services that have both IPv4 and IPv6 endpoints, but you can configure the Ingress Controller for single-stack or dual-stack services.
Prerequisites
You deployed an OKD cluster on bare metal.
You installed the OpenShift CLI (
oc
).
Procedure
To have the Ingress Controller serve traffic over IPv4/IPv6 to a workload, you can create a service YAML file or modify an existing service YAML file by setting the
ipFamilies
andipFamilyPolicy
fields. For example:Sample service YAML file
apiVersion: v1
kind: Service
metadata:
creationTimestamp: yyyy-mm-ddT00:00:00Z
labels:
name: <service_name>
manager: kubectl-create
operation: Update
time: yyyy-mm-ddT00:00:00Z
name: <service_name>
namespace: <namespace_name>
resourceVersion: "<resource_version_number>"
selfLink: "/api/v1/namespaces/<namespace_name>/services/<service_name>"
uid: <uid_number>
spec:
clusterIP: 172.30.0.0/16
clusterIPs: (1)
- 172.30.0.0/16
- <second_IP_address>
ipFamilies: (2)
- IPv4
- IPv6
ipFamilyPolicy: RequireDualStack (3)
ports:
- port: 8080
protocol: TCP
targetport: 8080
selector:
name: <namespace_name>
sessionAffinity: None
type: ClusterIP
status:
loadbalancer: {}
1 In a dual-stack instance, there are two different clusterIPs
provided.2 For a single-stack instance, enter IPv4
orIPv6
. For a dual-stack instance, enter bothIPv4
andIPv6
.3 For a single-stack instance, enter SingleStack
. For a dual-stack instance, enterRequireDualStack
.These resources generate corresponding
endpoints
. The Ingress Controller now watchesendpointslices
.To view
endpoints
, enter the following command:$ oc get endpoints
To view
endpointslices
, enter the following command:$ oc get endpointslices