Routes

Overview of Routes

An OpenShift Container Platform route exposes a service at a host name, such as www.example.com, so that external clients can reach it by name. Each route consists of a name (limited to 63 characters), a service selector, and an optional security configuration.

In order for services to be exposed externally, a 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.

A Route with a Specified Host
1
2
3
4
5
6
7
8
9
  apiVersion: route.openshift.io/v1
  kind: Route
  metadata:
    name: host-route
  spec:
    host: www.example.com
    to:
      kind: Service
      name: service-name

A Route Without a Host
1
2
3
4
5
6
7
8
  apiVersion: route.openshift.io/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 Container Platform automatically generates one for you. The generated host name is of the form:

<route-name>[-<namespace>].<suffix>

The following example shows the OpenShift Container Platform-generated host name for the above configuration of a route without a host added to a namespace mynamespace:

Generated Host Name
1
     no-route-hostname-mynamespace.router.default.svc.cluster.local

The generated host name suffix is the default routing subdomainrouter.default.svc.cluster.local.

A cluster administrator can also customise the suffix used as the default routing subdomain for their environment.

Route Types

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.

Unsecured Routes

Unsecured Route Object YAML Definition
1
2
3
4
5
6
7
8
9
  apiVersion: route.openshift.io/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 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 host name and path are passed through to the backend server so it should be able to successfully answer requests for them. For example: a request to http://example.com/foo/ that goes to the router will result in a pod seeing a request to http://example.com/foo/.

An Unsecured Route with a Path
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  apiVersion: route.openshift.io/v1
  kind: Route
  metadata:
   name: route-unsecured
  spec:
    host: www.example.com
    path: "/test"
    to:
      kind: Service
      name: service-name

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

Secured routes specify the TLS termination of the route and, optionally, provide a key and certificate(s).

TLS termination in OpenShift Container Platform relies on Server Name Indication (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.

A Secured Route Using Edge Termination
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  apiVersion: route.openshift.io/v1
  kind: Route
  metadata:
    name: route-edge-secured
  spec:
    host: www.example.com
    to:
      kind: Service
      name: service-name
    tls:
      termination: edge
      key: |-
      -----BEGIN PRIVATE KEY-----
      [...]
      -----END PRIVATE KEY-----
      certificate: |-
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----
      caCertificate: |-
      -----BEGIN CERTIFICATE-----
      [...]
      -----END CERTIFICATE-----

Lines Options
4, 9 The name of the object, which is limited to 63 characters.
11 The termination field is edge for edge termination.
12 The key field is the contents of the PEM format key file.
16 The certificate field is the contents of the PEM format certificate file.
20 The certificate field is the contents of the PEM format certificate file.

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.

A Secured Route Using Edge Termination Allowing HTTP Traffic
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  apiVersion: route.openshift.io/v1
  kind: Route
  metadata:
    name: route-edge-secured-allow-insecure
  spec:
    host: www.example.com
    to:
      kind: Service
      name: service-name
    tls:
      termination:                   edge
      insecureEdgeTerminationPolicy: Allow
      [ ... ]

Lines Options
4, 9 The name of the object, which is limited to 63 characters.
11 The termination field is edge for edge termination.
12 The insecure policy to allow requests sent on an insecure scheme HTTP.

A Secured Route Using Edge Termination Redirecting HTTP Traffic to HTTPS
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
      apiVersion: route.openshift.io/v1
      kind: Route
      metadata:
        name: route-edge-secured-redirect-insecure
      spec:
        host: www.example.com
        to:
          kind: Service
          name: service-name
        tls:
          termination:                   edge
          insecureEdgeTerminationPolicy: Redirect
          [ ... ]

Lines Options
4, 9 The name of the object, which is limited to 63 characters.
11 The termination field is edge for edge termination.
12 The insecure policy to redirect requests sent on an insecure 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.

A Secured Route Using Passthrough Termination
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: route-passthrough-secured
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name
  tls:
    termination: passthrough

Lines Options
4, 9 The name of the object, which is limited to 63 characters.
11 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 insecureEdgeTerminationPolicy. The only valid values are None (or empty, for disabled) or Redirect.


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.

A Secured Route Using Re-Encrypt Termination
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: route-reencrypt-secured
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name
  tls:
    termination: reencrypt
    key: [as in edge termination]
    certificate: [as in edge termination]
    caCertificate: [as in edge termination]
    destinationCACertificate: |-
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----

Lines Options
4, 9 The name of the object, which is limited to 63 characters.
11 The termination field is reencrypt for edge termination.
15 Required for re-encryption, destinationCACertificate specifies a CA certificate to validate the endpoint certificate, securing the connection from the router to the destination pods. This field can be omitted if the service is using a service signing certificate, or the administrator has specified a default CA certificate for the router and the service has a certificate signed by that CA.

If the destinationCACertificate field is left empty, the router automatically leverages the certificate authority that is generated for service serving certificates, and is injected into every pod as /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt. This allows new routes that leverage end-to-end encryption without having to generate a certificate for the route. This is useful for custom routers or the F5 router, which may prevent the destinationCACertificate unless the administrator has allowed it.

Re-encrypt routes can have an insecureEdgeTerminationPolicy with all of the same values as edge-terminated routes.


Routes using Health monitors

Specify virtual-server.f5.com/health annotation for configuring any route with a health monitor.

A Secured Route Using HTTPS health monitor
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: route-reencrypt-https-monitor
  annotations:
     virtual-server.f5.com/health: |
        [
           {
              "send": "HTTP GET /pyapps",
              "interval": 5,
              "timeout": 16,
              "type": "https",
           }
        ]
spec:
  host: www.example.com
  to:
    kind: Service
    name: service-name
  tls:
    termination: reencrypt
    key: [as in edge termination]
    certificate: [as in edge termination]
    caCertificate: [as in edge termination]
    destinationCACertificate: |-
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----

How to deploy Routes

Quickstart

Deploying a route has two steps:

  • Create a route configuration file
  • Create a route resource in the environment using OpenShift cli

But, before creating a route, the services that routes expose need to be created along with the pods.

  1. Create two services and corresponding pods:

    foo-app.yaml
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
      kind: Pod
      apiVersion: v1
      metadata:
        name: foo-app
        labels:
          app: foo
      spec:
        containers:
          - name: foo-app
            image: f5/img
            args:
              - "-text=foo"
    
      ---
    
      kind: Service
      apiVersion: v1
      metadata:
        name: foo-service
      spec:
        selector:
          app: foo
        ports:
          - port: 5678 # Default port for image
    
    bar-app.yaml
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
      kind: Pod
      apiVersion: v1
      metadata:
        name: bar-app
        labels:
          app: bar
      spec:
        containers:
          - name: bar-app
            image: f5/img
            args:
              - "-text=bar"
    
      ---
    
      kind: Service
      apiVersion: v1
      metadata:
        name: bar-service
      spec:
        selector:
          app: bar
        ports:
          - port: 5678 # Default port for image
    
  2. Using foo-app.yaml and bar-app.yaml, create the pods and services using OpenShift cli:

    oc create -f foo-app.yaml -f bar-app.yaml
    
  3. As the application pods and services are created, expose these services using routes:

    bar-app.yaml
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: route-foo
    spec:
      host: www.example.com
      path: "/foo"
      to:
        kind: Service
        name: foo-service
    
    ---
    
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: route-bar
    spec:
      host: www.example.com
      path: "/bar"
      to:
        kind: Service
        name: bar-service
    

    In route-config.yaml, there are two routes with host name www.example.com with path “/foo” exposes “foo-service” and path “/bar” exposes “bar-service”.

    oc create -f route-config.yaml
    

    Now you have successfully deployed and the applications, services and exposed them using routes.

  4. Create secure routes to route the traffic with TLS:

    routes-config-secure.yaml
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: route-foo-edge-secured
    spec:
      host: www.example.com
      path: "/foo"
      to:
        kind: Service
        name: foo-service
      tls:
        termination: edge
        key: |-
        -----BEGIN PRIVATE KEY-----
        [...]
        -----END PRIVATE KEY-----
        certificate: |-
        -----BEGIN CERTIFICATE-----
        [...]
        -----END CERTIFICATE-----
        caCertificate: |-
        -----BEGIN CERTIFICATE-----
        [...]
        -----END CERTIFICATE-----
    
    ---
    
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: route-bar-reencrypt-secured
    spec:
      host: www.example.com
      path: "/bar"
      to:
        kind: Service
        name: bar-service
      tls:
        termination: reencrypt
        key: [as in edge termination]
        certificate: [as in edge termination]
        caCertificate: [as in edge termination]
        destinationCACertificate: |-
        -----BEGIN CERTIFICATE-----
        [...]
        -----END CERTIFICATE-----
    

    Push this configuration with the following command:

    oc create -f route-config-secure.yaml
    
  5. To view the contents or check the status of a route:

    oc describe route <route-name>
    
  6. To delete a route:

    oc delete route <route-name>
    

Examples Repository

View more examples on GitHub.


Note

To provide feedback on Container Ingress Services or this documentation, please file a GitHub Issue.