An OpenShift Origin route exposes a service at a host name, like www.example.com, so that external clients can reach it by name.
DNS resolution for a host name is handled separately from routing. Your administrator may have configured a DNS wildcard entry that will resolve to the OpenShift Origin node that is running the OpenShift Origin router. If you are using a different host name you may need to modify its DNS records independently to resolve to the node that is running the router.
Each route consists of a name (limited to 63 characters), a service selector, and an optional security configuration.
An OpenShift Origin administrator can deploy routers to nodes in an OpenShift Origin cluster, which enable routes created by developers to be used by external clients. The routing layer in OpenShift Origin is pluggable, and two available router plug-ins are provided and supported by default.
See the Installation and Configuration guide for information on deploying a router. |
A router uses the service selector to find the service and the endpoints backing the service. When both router and service provide load balancing, OpenShift Origin uses the router load balancing. A routers detects relevant changes in the IP addresses of its services, and adapts its configuration accordingly. This is useful for custom routers to communicate modifications of API objects to an external routing solution.
The path of a request starts with the DNS resolution of a host name to one or more routers. The suggested method is to define a cloud domain with a wildcard DNS entry pointing to one or more virtual IP (VIP) addresses backed by multiple router instances. Routes using names and addresses outside the cloud domain require configuration of individual DNS entries.
When there are fewer VIP addresses than routers, the routers corresponding to the number of addresses are active and the rest are passive. A passive router is also known as a hot-standby router. For example, with two VIP addresses and three routers, you have an "active-active-passive" configuration. See High Availability for more information on router VIP configuration.
Routes can be sharded among the set of routers. Administrators can set up sharding on a cluster-wide basis and users can set up sharding for the namespace in their project. Sharding allows the operator to define multiple router groups. Each router in the group serves only a subset of traffic.
OpenShift Origin routers provide external host name mapping and load balancing of service end points over protocols that pass distinguishing information directly to the router; the host name must be present in the protocol in order for the router to determine where to send it.
Router plug-ins assume they can bind to host ports 80 (HTTP)
and 443 (HTTPS), by default.
This means that routers must be placed on nodes
where those ports are not otherwise in use.
Alternatively, a router can be configured to listen
on other ports by setting the ROUTER_SERVICE_HTTP_PORT
and ROUTER_SERVICE_HTTPS_PORT
environment variables.
Because a router binds to ports on the host node, only one router listening on those ports can be on each node if the router uses host networking (the default). Cluster networking is configured such that all routers can access all pods in the cluster.
Routers support the following protocols:
HTTP
HTTPS (with SNI)
WebSockets
TLS with SNI
WebSocket traffic uses the same route conventions and supports the same TLS termination types as other traffic. |
A template router is a type of router that provides certain infrastructure information to the underlying router implementation, such as:
A wrapper that watches endpoints and routes.
Endpoint and route data, which is saved into a consumable form.
Passing the internal state to a configurable template and executing the template.
Calling a reload script.
The following router plug-ins are provided and supported in OpenShift Origin. Instructions on deploying these routers are available in Deploying a Router.
The HAProxy template router implementation is the reference implementation for a template router plug-in. It uses the openshift/origin-haproxy-router repository to run an HAProxy instance alongside the template router plug-in.
The following diagram illustrates how data flows from the master through the plug-in and finally into an HAProxy configuration:
Sticky sessions attempts to ensure that user traffic is directed to the same pod in each session, and improves application user experience by caching data. For example, for a cluster with five back-end pods, and two load-balanced routers, you can ensure that the same pod receives the web traffic from the same web browser regardless of the router that handles it.
While placing returning traffic onto the same pod cannot be guaranteed, you can use HTTP headers to set a cookie determining the pod used by the last connection, in an attempt to steer traffic to the same pod. When the application user hits the router the browser re-sends the cookie and knows where to send the traffic.
As a cluster administrator, you can turn off the stickiness for passthrough routes separately from other connections, or turn off stickiness entirely.
By default, if the default HAProxy router is using passthrough routes, sticky
sessions are implemented using the balance source
directive in the underlying
router configuration, which balances based on the source IP. Other types of
routes use balance leastconn
by default. If a cookie is present, it is read
and sent to the same pod it went to last time if the pod still exists. If no
cookie is present, because this is a new session, stickiness is disabled, or
it’s using a passthrough route, the router picks a 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 back-end. If back-ends change, the traffic could head to the wrong server, making it less sticky, and if you are using a load-balancer (which hides the source IP) the same number is set for all connections and traffic is sent to the same pod. |
In addition, the template router plug-in provides the service name and namespace to the underlying implementation. This can be used for more advanced configuration such as implementing stick-tables that synchronize between a set of peers.
Specific configuration for this router implementation is stored in the haproxy-config.template file located in the /var/lib/haproxy/conf directory of the router container.
The |
For all the items outlined in this section, you can set environment
variables on the deployment config for the router to alter its configuration, or use the oc set env
command:
$ oc set env <object_type>/<object_name> KEY1=VALUE1 KEY2=VALUE2
For example:
$ oc set env dc/router ROUTER_SYSLOG_ADDRESS=127.0.0.1 ROUTER_LOG_LEVEL=debug
Variable | Default | Description |
---|---|---|
|
The contents of a default certificate to use for routes that don’t expose a TLS server cert; in PEM format. |
|
|
A path to a directory that contains a file named tls.crt. If tls.crt is not a PEM file which also contains a private key, it is first combined with a file named tls.key in the same directory. The PEM-format contents are then used as the default certificate. Only used if |
|
|
A path to default certificate to use for routes that don’t expose a TLS server cert; in PEM format. Only used if |
|
|
|
If |
|
A label selector to apply to namespaces to watch, empty means all. |
|
|
A label selector to apply to projects to watch, emtpy means all. |
|
|
The path to the reload script to use to reload the router. |
|
|
A comma-separated list of domains that the host name in a route can only be part of. Any subdomain in the domain can be used. Option |
|
|
5000ms |
Length of time between subsequent "liveness" checks on backends. (TimeUnits) |
|
"text/html text/plain text/css" |
A space separated list of mime types to compress. |
|
30s |
Length of time within which a client has to acknowledge or send data. (TimeUnits) |
|
5s |
The maximum connect time. (TimeUnits) |
|
30s |
Length of time within which a server has to acknowledge or send data. (TimeUnits) |
|
1h |
Length of time till which TCP or WebSocket connections will remain open. If you have websockets/tcp connections (and any time HAProxy is reloaded), the old HAProxy processes will "linger" around for that period. (TimeUnits) |
|
A comma-separated list of domains that the host name in a route can not be part of. No subdomain in the domain can be used either. Overrides option |
|
|
If |
|
|
warning |
The log level to send to the syslog server. |
|
20000 |
Maximum number of concurrent connections. |
|
If set |
|
|
443 |
Port to listen for HTTPS requests. |
|
80 |
Port to listen for HTTP requests. |
|
public |
The name that the router identifies itself in the in route status. |
|
The (optional) host name of the router shown in the in route status. |
|
|
The namespace the router identifies itself in the in route status. Required if |
|
|
10443 |
Internal port for some front-end to back-end communication (see note below). |
|
10444 |
Internal port for some front-end to back-end communication (see note below). |
|
300s |
Set the maximum time to wait for a new HTTP request to appear. If this is set too low, it can confuse browsers and applications not expecting a small |
|
10s |
Length of time the transmission of an HTTP request can take. (TimeUnits) |
|
The template that should be used to generate the host name for a route without spec.host (e.g. ${name}-${namespace}.myapps.mycompany.com). |
|
|
Address to send log messages. Disabled if empty. |
|
|
source |
Load-balancing strategy for multiple endpoints for pass-through routes. Available options are |
|
leastconn |
Load-balancing strategy routes with multiple endpoints. Available options are |
|
A label selector to apply to the routes to watch, empty means all. |
|
|
The password needed to access router stats (if the router implementation supports it). |
|
|
Port to expose statistics on (if the router implementation supports it). If not set, stats are not exposed. |
|
|
The user name needed to access router stats (if the router implementation supports it). |
|
|
|
The path to the HAProxy template file (in the container image). |
|
12s |
The minimum frequency the router is allowed to reload to accept new changes. (TimeUnits) |
|
When set to |
|
|
When set to |
|
|
Set to |
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)
If you want to run multiple routers on the same machine, you must change the
ports that the router is listening on, |
The F5 router plug-in integrates with an existing F5 BIG-IP® system in your environment. F5 BIG-IP® version 11.4 or newer is required in order to have the F5 iControl REST API. The F5 router supports unsecured, edge terminated, re-encryption terminated, and passthrough terminated routes matching on HTTP vhost and request path.
The F5 router has feature parity with the HAProxy template router, and has additional features over the F5 BIG-IP® support in OpenShift v2. Compared with the routing-daemon used in earlier versions, the F5 router additionally supports:
path-based routing (using policy rules),
re-encryption (implemented using client and server SSL profiles), and
passthrough of encrypted connections (implemented using an iRule that parses the SNI protocol and uses a data group that is maintained by the F5 router for the servername lookup).
Passthrough routes are a special case: path-based routing is technically impossible with passthrough routes because F5 BIG-IP® itself does not see the HTTP request, so it cannot examine the path. The same restriction applies to the template router; it is a technical limitation of passthrough encryption, not a technical limitation of OpenShift Origin. |
Because F5 BIG-IP® is external to the OpenShift SDN, a cluster administrator must create a peer-to-peer tunnel between F5 BIG-IP® and a host that is on the SDN, typically an OpenShift Origin node host. This ramp node can be configured as unschedulable for pods so that it will not be doing anything except act as a gateway for the F5 BIG-IP® host. It is also possible to configure multiple such hosts and use the OpenShift Origin ipfailover feature for redundancy; the F5 BIG-IP® host would then need to be configured to use the ipfailover VIP for its tunnel’s remote endpoint.
The operation of the F5 router is similar to that of the OpenShift Origin routing-daemon used in earlier versions. Both use REST API calls to:
create and delete pools,
add endpoints to and delete them from those pools, and
configure policy rules to route to pools based on vhost.
Both also use scp
and ssh
commands to upload custom TLS/SSL certificates to
F5 BIG-IP®.
The F5 router configures pools and policy rules on virtual servers as follows:
When a user creates or deletes a route on OpenShift Origin, the router creates a pool to F5 BIG-IP® for the route (if no pool already exists) and adds a rule to, or deletes a rule from, the policy of the appropriate vserver: the HTTP vserver for non-TLS routes, or the HTTPS vserver for edge or re-encrypt routes. In the case of edge and re-encrypt routes, the router also uploads and configures the TLS certificate and key. The router supports host- and path-based routes.
Passthrough routes are a special case: to support those, it is necessary to write an iRule that parses the SNI ClientHello handshake record and looks up the servername in an F5 data-group. The router creates this iRule, associates the iRule with the vserver, and updates the F5 data-group as passthrough routes are created and deleted. Other than this implementation detail, passthrough routes work the same way as other routes. |
When a user creates a service on OpenShift Origin, the router adds a pool to F5 BIG-IP® (if no pool already exists). As endpoints on that service are created and deleted, the router adds and removes corresponding pool members.
When a user deletes the route and all endpoints associated with a particular pool, the router deletes that pool.
With native integration of F5 with OpenShift Origin, you do not need to configure a ramp node for F5 to be able to reach the pods on the overlay network as created by OpenShift SDN.
Connection
The F5 appliance can connect to the OpenShift Origin cluster via an L3 connection. An L2 switch connectivity is not required between OpenShift Origin nodes. On the appliance, you can use multiple interfaces to manage the integration:
Management interface - Reaches the web console of the F5 appliance.
External interface - Configures the virtual servers for inbound web traffic.
Internal interface - Programs the appliance and reaches out to the pods.
An F5 controller pod has admin
access to the appliance. The F5 image is
launched within the OpenShift Origin cluster (scheduled on any node) that uses
iControl REST APIs to program the virtual servers with policies, and configure
the VxLAN device.
Data Flow: Packets to Pods
This section explains how the packets reach the pods, and vice versa. These actions are performed by the F5 controller pod and the F5 appliance, not the user. |
When natively integrated, The F5 appliance reaches out to the pods directly using VxLAN encapsulation. This integration works only when OpenShift Origin is using openshift-sdn as the network plug-in. The openshift-sdn plug-in employs VxLAN encapsulation for the overlay network that it creates.
To make a successful data path between a pod and the F5 appliance:
F5 needs to encapsulate the VxLAN packet meant for the pods. This requires the sdn-services license add-on. A VxLAN device needs to be created and the pod overlay network needs to be routed through this device.
F5 needs to know the VTEP IP address of the pod, which is the IP address of the node where the pod is located.
F5 needs to know which source-ip
to use for the overlay network when
encapsulating the packets meant for the pods. This is known as the gateway address.
OpenShift Origin nodes need to know where the F5 gateway address is (the VTEP address for the return traffic). This needs to be the internal interface’s address. All nodes of the cluster must learn this automatically.
Since the overlay network is multi-tenant aware, F5 must use a VxLAN ID that is
representative of an admin
domain, ensuring that all tenants are reachable by
the F5. Ensure that F5 encapsulates all packets with a vnid
of 0
(the
default vnid
for the admin
namespace in OpenShift Origin) by putting an
annotation on the manually created hostsubnet
-
pod.network.openshift.io/fixed-vnid-host: 0
.
A ghost hostsubnet
is manually created as part of the setup, which fulfills
the third and forth listed requirements. When the F5 controller pod is launched,
this new ghost hostsubnet
is provided so that the F5 appliance can be
programmed suitably.
The term ghost |
The first requirement is fulfilled by the F5 controller pod once it is launched.
The second requirement is also fulfilled by the F5 controller pod, but it is an
ongoing process. For each new node that is added to the cluster, the controller
pod creates an entry in the VxLAN device’s VTEP FDB. The controller pod needs
access to the nodes
resource in the cluster, which you can accomplish by
giving the service account appropriate privileges. Use the following command:
$ oadm policy add-cluster-role-to-user system:sdn-reader system:serviceaccount:default:router
Data Flow from the F5 Host
These actions are performed by the F5 controller pod and the F5 appliance, not the user. |
The destination pod is identified by the F5 virtual server for a packet.
VxLAN dynamic FDB is looked up with pod’s IP address. If a MAC address is found, go to step 5.
Flood all entries in the VTEP FDB with ARP requests seeking the pod’s MAC address.
One of the nodes (VTEP) will respond, confirming that it is the one where the pod is located. An entry is made into the VxLAN dynamic FDB with the pod’s MAC address and the VTEP to be used as the value.
Encap an IP packet with VxLAN headers, where the MAC of the pod and the VTEP of the node is given as values from the VxLAN dynamic FDB.
Calculate the VTEP’s MAC address by sending out an ARP or checking the host’s neighbor cache.
Deliver the packet through the F5 host’s internal address.
Data Flow: Return Traffic to the F5 Host
These actions are performed by the F5 controller pod and the F5 appliance, not the user. |
The pod sends back a packet with the destination as the F5 host’s VxLAN gateway address.
The openvswitch
at the node determines that the VTEP for this packet is the
F5 host’s internal interface address. This is learned from the ghost hostsubnet
creation.
A VxLAN packet is sent out to the internal interface of the F5 host.
During the entire data flow, the VNID is pre-fixed to be |
In order for services to be exposed externally, an OpenShift Origin route allows you to associate a service with an externally-reachable host name. This edge host name is then used to route traffic to the service.
When multiple routes from different namespaces claim the same host, the oldest route wins and claims it for the namespace. If additional routes with different path fields are defined in the same namespace, those paths are added. If multiple routes with the same path are used, the oldest takes priority.
A consequence of this behavior is that if you have two routes for a host name: an older one and a newer one. If someone else has a route for the same host name that they created between when you created the other two routes, then if you delete your older route, your claim to the host name will no longer be in effect. The other namespace now claims the host name and your claim is lost.
apiVersion: v1
kind: Route
metadata:
name: host-route
spec:
host: www.example.com (1)
to:
kind: Service
name: service-name
1 | Specifies the externally-reachable host name used to expose a service. |
apiVersion: v1
kind: Route
metadata:
name: no-route-hostname
spec:
to:
kind: Service
name: service-name
If a host name is not provided as part of the route definition, then OpenShift Origin automatically generates one for you. The generated host name is of the form:
<route-name>[-<namespace>].<suffix>
The following example shows the OpenShift Origin-generated host name for the above configuration of a route without a host added to a namespace mynamespace:
no-route-hostname-mynamespace.router.default.svc.cluster.local (1)
1 | The generated host name suffix is the default routing subdomain router.default.svc.cluster.local. |
A cluster administrator can also customize the suffix used as the default routing subdomain for their environment.
Routes can be either secured or unsecured. Secure routes provide the ability to use several types of TLS termination to serve certificates to the client. Routers support edge, passthrough, and re-encryption termination.
apiVersion: v1
kind: Route
metadata:
name: route-unsecured
spec:
host: www.example.com
to:
kind: Service
name: service-name
Unsecured routes are simplest to configure, as they require no key or certificates, but secured routes offer security for connections to remain private.
A secured route is one that specifies the TLS termination of the route. The available types of termination are described below.
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) such that multiple routes can be served using the same host name, 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/test |
Yes (Matched by the host, not the route) |
www.example.com |
Yes |
apiVersion: 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. |
Secured routes specify the TLS termination of the route and, optionally, provide a key and certificate(s).
TLS termination in OpenShift Origin relies on SNI for serving custom certificates. Any non-SNI traffic received on port 443 is handled with TLS termination and a default certificate (which may not match the requested host name, resulting in validation errors). |
Secured routes can use any of the following three types of secure TLS termination.
Edge Termination
With edge termination, TLS termination occurs at the router, prior to proxying traffic to its destination. TLS certificates are served by the front end of the router, so they must be configured into the route, otherwise the router’s default certificate will be used for TLS termination.
apiVersion: v1
kind: Route
metadata:
name: route-edge-secured (1)
spec:
host: www.example.com
to:
kind: Service
name: service-name (1)
tls:
termination: edge (2)
key: |- (3)
-----BEGIN PRIVATE KEY-----
[...]
-----END PRIVATE KEY-----
certificate: |- (4)
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
caCertificate: |- (5)
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
1 | The name of the object, which is limited to 63 characters. |
2 | The termination field is edge for edge termination. |
3 | The key field is the contents of the PEM format key file. |
4 | The certificate field is the contents of the PEM format certificate file. |
5 | An optional CA certificate may be required to establish a certificate chain for validation. |
Because TLS is terminated at the router, connections from the router to the endpoints over the internal network are not encrypted.
Edge-terminated routes can specify an insecureEdgeTerminationPolicy
that
enables traffic on insecure schemes (HTTP
) to be disabled, allowed or
redirected.
The allowed values for insecureEdgeTerminationPolicy
are:
None
or empty (for disabled), Allow
or Redirect
.
The default insecureEdgeTerminationPolicy
is to disable traffic on the
insecure scheme. A common use case is to allow content to be served via a
secure scheme but serve the assets (example images, stylesheets and
javascript) via the insecure scheme.
apiVersion: v1
kind: Route
metadata:
name: route-edge-secured-allow-insecure (1)
spec:
host: www.example.com
to:
kind: Service
name: service-name (1)
tls:
termination: edge (2)
insecureEdgeTerminationPolicy: Allow (3)
[ ... ]
1 | The name of the object, which is limited to 63 characters. |
2 | The termination field is edge for edge termination. |
3 | The insecure policy to allow requests sent on an insecure scheme HTTP . |
apiVersion: v1
kind: Route
metadata:
name: route-edge-secured-redirect-insecure (1)
spec:
host: www.example.com
to:
kind: Service
name: service-name (1)
tls:
termination: edge (2)
insecureEdgeTerminationPolicy: Redirect (3)
[ ... ]
1 | The name of the object, which is limited to 63 characters. |
2 | The termination field is edge for edge termination. |
3 | The insecure policy to redirect requests sent on an i/nsecure scheme HTTP to a secure scheme HTTPS . |
Passthrough Termination
With passthrough termination, encrypted traffic is sent straight to the destination without the router providing TLS termination. Therefore no key or certificate is required.
apiVersion: v1
kind: Route
metadata:
name: route-passthrough-secured (1)
spec:
host: www.example.com
to:
kind: Service
name: service-name (1)
tls:
termination: passthrough (2)
1 | The name of the object, which is limited to 63 characters. |
2 | The termination field is set to passthrough . No other encryption fields are needed. |
The destination pod is responsible for serving certificates for the traffic at the endpoint. This is currently the only method that can support requiring client certificates (also known as two-way authentication).
Passthrough routes can also have an |
Re-encryption Termination
Re-encryption is a variation on edge termination where the router terminates TLS with a certificate, then re-encrypts its connection to the endpoint which may have a different certificate. Therefore the full path of the connection is encrypted, even over the internal network. The router uses health checks to determine the authenticity of the host.
apiVersion: v1
kind: Route
metadata:
name: route-pt-secured (1)
spec:
host: www.example.com
to:
kind: Service
name: service-name (1)
tls:
termination: reencrypt (2)
key: [as in edge termination]
certificate: [as in edge termination]
caCertificate: [as in edge termination]
destinationCACertificate: |- (3)
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
1 | The name of the object, which is limited to 63 characters. |
2 | The termination field is set to reencrypt . Other fields are as in edge
termination. |
3 | The destinationCACertificate field specifies a CA certificate to
validate the endpoint certificate, securing the connection from the router to
the destination. This field is required, but only for re-encryption. |
Re-encrypt routes can have an |
In OpenShift Origin, each route can have any number of
labels
in its metadata
field.
A router uses selectors (also known as a selection expression)
to select a subset of routes from the entire pool of routes to serve.
A selection expression can also involve
labels on the route’s namespace.
The selected routes form a router shard.
You can
create
and
modify
router shards independently from the routes, themselves.
This design supports traditional sharding as well as overlapped sharding.
In traditional sharding, the selection results in no overlapping sets
and a route belongs to exactly one shard.
In overlapped sharding, the selection results in overlapping sets
and a route can belong to many different shards.
For example, a single route may belong to a SLA=high
shard
(but not SLA=medium
or SLA=low
shards),
as well as a geo=west
shard
(but not a geo=east
shard).
Another example of overlapped sharding is a set of routers that select based on namespace of the route:
Router | Selection | Namespaces |
---|---|---|
router-1 |
|
|
router-2 |
|
|
router-3 |
|
|
Both router-2
and router-3
serve routes that are in the
namespaces Q*
, R*
, S*
, T*
.
To change this example from overlapped to traditional sharding,
we could change the selection of router-2
to K*
— P*
,
which would eliminate the overlap.
When routers are sharded, a given route is bound to zero or more routers in the group. The route binding ensures uniqueness of the route across the shard. Uniqueness allows secure and non-secure versions of the same route to exist within a single shard. This implies that routes now have a visible life cycle that moves from created to bound to active.
In the sharded environment the first route to hit the shard reserves the right to exist there indefinitely, even across restarts.
During a green/blue deployment a route may be be selected in multiple routers. An OpenShift Origin application administrator may wish to bleed traffic from one version of the application to another and then turn off the old version.
Sharding can be done by the administrator at a cluster level and by the user
at a project/namespace level.
When namespace labels are used, the service account for the router
must have cluster-reader
permission to permit the
router to access the labels in the namespace.
For two or more routes that claim the same host name, the resolution order is based on the age of the route and the oldest route would win the claim to that host. In the case of sharded routers, routes are selected based on their labels matching the router’s selection criteria. There is no consistent way to determine when labels are added to a route. So if an older route claiming an existing host name is "re-labelled" to match the router’s selection criteria, it will replace the existing route based on the above mentioned resolution order (oldest route wins). |
Using environment variables as defined in Configuration Parameters, a router 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.
Route Annotations
For all the items outlined in this section, you can set annotations on the route definition for the route to alter its configuration
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 |
|
|
Setting |
|
|
Limits the number of concurrent TCP connections shared by an IP address. |
|
|
Limits the rate at which an IP address can make HTTP requests. |
|
|
Limits the rate at which an IP address can make TCP connections. |
|
|
Sets a server-side timeout for the route. (TimeUnits) |
|
|
Sets the interval for the back-end health checks. (TimeUnits) |
|
apiVersion: 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 unit 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 wildcard policy allows a user to define a route that covers all hosts within a
domain (when the router is configured to allow it). A route can specify a
wildcard policy as part of its configuration using the wildcardPolicy
field.
Any routers run with a policy allowing wildcard routes will expose the route
appropriately based on the wildcard policy.
apiVersion: v1
kind: Route
spec:
host: wildcard.example.com (1)
wildcardPolicy: Subdomain (2)
to:
kind: Service
name: service-name
1 | Specifies the externally reachable host name used to expose a service. |
2 | Specifies that the externally reachable host name should allow all hosts
in the subdomain example.com . *.example.com is the subdomain for host
name wildcard.example.com to reach the exposed service. |
The route status
field is only set by routers. If changes are made to a route
so that a router no longer serves a specific route, the status becomes stale.
The routers do not clear the route status
field. To remove the stale entries
in the route status, use the
clear-route-status
script.
A router can be configured to deny or allow a specific subset of domains from
the host names in a route using the ROUTER_DENIED_DOMAINS
and
ROUTER_ALLOWED_DOMAINS
environment variables.
|
Domains listed are not allowed in any indicated routes. |
|
Only the domains listed are allowed in any indicated routes. |
The domains in the list of denied domains take precedence over the list of allowed domains. Meaning OpenShift Origin first checks the deny list (if applicable), and if the host name is not in the list of denied domains, it then checks the list of allowed domains. However, the list of allowed domains is more restrictive, and ensures that the router only admits routes with hosts that belong to that list.
For example, to deny the [*.]open.header.test
, [*.]openshift.org
and
[*.]block.it
routes for the myrouter
route:
$ oadm router myrouter ... $ oc set env dc/myrouter ROUTER_DENIED_DOMAINS="open.header.test, openshift.org, block.it"
This means that myrouter
will admit the following based on the route’s name:
$ oc expose service/<name> --hostname="foo.header.test" $ oc expose service/<name> --hostname="www.allow.it" $ oc expose service/<name> --hostname="www.openshift.test"
However, myrouter
will deny the following:
$ oc expose service/<name> --hostname="open.header.test" $ oc expose service/<name> --hostname="www.open.header.test" $ oc expose service/<name> --hostname="block.it" $ oc expose service/<name> --hostname="franco.baresi.block.it" $ oc expose service/<name> --hostname="openshift.org" $ oc expose service/<name> --hostname="api.openshift.org"
Alternatively, to block any routes where the host name is not set to [*.]stickshift.org
or [*.]kates.net
:
$ oadm router myrouter ... $ oc set env dc/myrouter ROUTER_ALLOWED_DOMAINS="stickshift.org, kates.net"
This means that the myrouter
router will admit:
$ oc expose service/<name> --hostname="stickshift.org" $ oc expose service/<name> --hostname="www.stickshift.org" $ oc expose service/<name> --hostname="kates.net" $ oc expose service/<name> --hostname="api.kates.net" $ oc expose service/<name> --hostname="erno.r.kube.kates.net"
However, myrouter
will deny the following:
$ oc expose service/<name> --hostname="www.open.header.test" $ oc expose service/<name> --hostname="drive.ottomatic.org" $ oc expose service/<name> --hostname="www.wayless.com" $ oc expose service/<name> --hostname="www.deny.it"
To implement both scenarios, run:
$ oadm router adrouter ... $ oc env dc/adrouter ROUTER_ALLOWED_DOMAINS="openshift.org, kates.net" \ ROUTER_DENIED_DOMAINS="ops.openshift.org, metrics.kates.net"
This will allow any routes where the host name is set to [*.]openshift.org
or
[*.]kates.net
, and not allow any routes where the host name is set to
[*.]ops.openshift.org
or [*.]metrics.kates.net
.
Therefore, the following will be denied:
$ oc expose service/<name> --hostname="www.open.header.test" $ oc expose service/<name> --hostname="ops.openshift.org" $ oc expose service/<name> --hostname="log.ops.openshift.org" $ oc expose service/<name> --hostname="www.block.it" $ oc expose service/<name> --hostname="metrics.kates.net" $ oc expose service/<name> --hostname="int.metrics.kates.net"
However, the following will be allowed:
$ oc expose service/<name> --hostname="openshift.org" $ oc expose service/<name> --hostname="api.openshift.org" $ oc expose service/<name> --hostname="m.api.openshift.org" $ oc expose service/<name> --hostname="kates.net" $ oc expose service/<name> --hostname="api.kates.net"
Hosts and subdomains are owned by the namespace of the route that first
makes the claim. Other routes created in the namespace can make claims on
the subdomain. All other namespaces are prevented from making claims on
the claimed hosts and subdomains. The namespace that owns the host also
owns all paths associated with the host, for example _www.abc.xyz/path1
.
For example, if the host www.abc.xyz
is not claimed by any route.
Creating route r1
with host www.abc.xyz
in namespace ns1
makes
namespace ns1
the owner of host www.abc.xyz
and subdomain abc.xyz
for wildcard routes. If another namespace, ns2
, tries to create a route
with say a different path www.abc.xyz/path1/path2
, it would fail
because a route in another namespace (ns1
in this case) owns that host.
With
wildcard routes
the namespace that owns the subdomain owns all hosts in the subdomain.
If a namespace owns subdomain abc.xyz
as in the above example,
another namespace cannot claim z.abc.xyz
.
By disabling the namespace ownership rules, you can disable these restrictions and allow hosts (and subdomains) to be claimed across namespaces.
If you decide to disable the namespace ownership checks in your router, be aware that this allows end users to claim ownership of hosts across namespaces. While this change can be desirable in certain development environments, use this feature with caution in production environments, and ensure that your cluster policy has locked down untrusted end users from creating routes. |
For example, with ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true
, if
namespace ns1
creates the oldest route r1
www.abc.xyz
, it owns only
the hostname (+ path). Another namespace can create a wildcard route
even though it does not have the oldest route in that subdomain (abc.xyz
)
and we could potentially have other namespaces claiming other
non-wildcard overlapping hosts (for example, foo.abc.xyz
, bar.abc.xyz
,
baz.abc.xyz
) and their claims would be granted.
Any other namespace (for example, ns2
) can now create
a route r2
www.abc.xyz/p1/p2
, and it would be admitted. Similarly
another namespace (ns3
) can also create a route wildthing.abc.xyz
with a subdomain wildcard policy and it can own the wildcard.
As this example demonstrates, the policy ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true
is more
lax and allows claims across namespaces. The only time the router would
reject a route with the namespace ownership disabled is if the host+path
is already claimed.
For example, if a new route rx
tries to claim www.abc.xyz/p1/p2
, it
would be rejected as route r2
owns that host+path combination. This is true whether route rx
is in the same namespace or other namespace since the exact host+path is already claimed.
This feature can be set during router creation or by setting an environment variable in the router’s deployment configuration.
$ oadm router ... --disable-namespace-ownership-check=true
$ oc env dc/router ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true