Routes

What is 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: 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: 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
     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: 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: 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: 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: 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: 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: 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: 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 might not allow 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.


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: v1
      kind: Route
      metadata:
        name: route-foo
      spec:
        host: www.example.com
        path: "/foo"
        to:
          kind: Service
          name: foo-service
    
      ---
    
      apiVersion: 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: 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: 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-----
    

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

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

    oc delete route <route-name>
    

Example Repository

See the repository on GitHub for more examples.


Note

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