OpenShift Route

Guide to OpenShift Tutorial
calendar June 16, 2022
Chapter 2 OpenShift Route

Openshift is a cloud-based Kubernetes service by RedHat. OpenShift routes enable access to pods (one or more containers deployed in a cluster) from external resources. In most cases, applications deployed on OpenShift expose external endpoints to the outside of the cluster through a router.

For example, if your Kubernetes workload is a web API (or any other interface external users need to access), you need to provide a route to the particular service or pod within OpenShift to access the required application or service. Each route consists of a name (limited to 63 characters), a service selector, and an optional security configuration.

An example of how to create a default route running the Nginx image on an OpenShift cluster.
An example of how to create a default route running the Nginx image on an OpenShift cluster.

To help you better understand the topic, we’ll take a closer look at the types of OpenShift routes and different methods for configuration and troubleshooting.

Types of OpenShift Routes

There are two types of OpenShift routes:

  1. HTTP routes (unsecured routes)
  2. HTTPS routes (secured routes)

Let’s start by looking at an unsecured route example.

Unsecured OpenShift Routes

Unsecured Routes in OpenShift use plaintext HTTP communication. You can create OpenShift routes through GUI/web console or CLI (command line interface). Below, we’ll walk through both methods

How to Create an Unsecured Route by Using Web Console

To create a route using the Web Console, navigate to the “Routes” page under the “Application” section. Select the "Create Route" option to configure and create the route.

Creating an unsecured route in the OpenShift GUI.
Creating an unsecured route in the OpenShift GUI. (Source).

How to Create an Unsecured Route Using CLI

Use the following command to create an unsecured route

$oc expose svc/service --hostname=www.example.com
                

This command exposes the service against the URL www.example.com. External users will be redirected to the service named service when accessing the URL www.example.com.

Below is the YAML definition for Unsecured Route Object:

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 much easier to maintain because they do not require a key or certificate.

OpenShift Path-Based Routes

Path-Based routes allow for a path to be specified within the route. It is then compared against a URL to either allow or disallow the traffic. Traffic for a Path-Based route should be HTTP-based (unsecured). The same hostname can be used to configure multiple routes, each with its path. The URL is compared to the routes, and the most specific route (best match) is chosen. In the case of multiple routes, the comparison will move to the following route until the best match is found. This is all configurable, and the comparison criteria can be configured in the router. The hostname and paths are sent back to the server for it to respond to its requests successfully.

For example, if the route www.example.com/test is compared to the URL www.example.com/test it will allow the traffic. However, it will not allow traffic compared to a URL of www.example.com.

On the other hand, if the route www.example.com is compared to the URL www.example.com/test, it will allow traffic based on the comparison match with the host and not the route.

Here is the YAML for 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                                
                

📝 Note: defining a route is the only additional attribute in path-based routing. Path-based routing is not secured and does not support TLS termination.

For more examples, visit the OpenShift Path-based Routing documentation.

Machine learning for Kubernetes sizing

Learn More
Visualize Utilization Metrics Set Resource Requests & Limits Set Requests & Limits with Machine Learning Identify mis-sized containers at a glance & automate resizing Get Optimal Node Configuration Recommendations
Kubernetes
Kubernetes + Densify

OpenShift Secured Routes

As the name suggests, Secured Routes are secured with TLS by providing a key and certificate. Secure routes offer various TLS terminations to serve certificates to the client. A TLS termination is the process of decrypting encrypted traffic. In OpenShift, TLS termination means terminating TLS encryption before passing the traffic to the required service or pod. Routers support edge, passthrough, and re-encryption termination.

TLS Termination in OpenShift uses SNI (Server Name Indication). SNI is an extension of the Transport Layer Security (TLS) network protocol. The client indicates which hostname it is trying to connect to at the beginning of the TLS handshake.

Non-SNI traffic routed to the secure port (default 443) is assigned a default certificate that most likely will not match the hostname, resulting in an authentication error.

You can learn more about secured routes in the OpenShift Route documentation.

OpenShift and the SNI Communication Flow

Below is an overview of an SNI communication flow:

The SNI Communication Flow.
The SNI Communication Flow. (Source)

Secured routes can use one of three types of secure TLS termination. The type of termination is determined by where the encryption is being terminated. The three termination types are:

  1. Edge Termination - Terminates encryption at the router.
  2. Passthrough Termination - Termination is passed from the router straight to the pod.
  3. Re-encryption Termination - Is like Edge Termination, but it adds encapsulation.

In the sections below, we’ll take a closer look at each type of termination.

Edge Termination

Edge termination terminates the encryption at the router. All communication till the router is secured, and any communication from the router to the endpoints is not. Since the encryption in edge termination is terminated at the router, the TLS certificate must be added to the route. If no certificate is specified, the router's default certificate is used and will likely result in an authentication error.

The screenshot below shows how edge termination is configured using a GUI. Note that there is an option in the screenshot below to deal with "Insecure traffic". Edge termination allows three different ways to treat insecure traffic. It can either be blocked, allowed, or redirected.

The following command is used to create a Secure Route with Edge Termination

The following command is used to create a Secure Route with Edge Termination

$oc create route edge --service=route-edge-secured --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=www.example.com                               
                

Note: Certificate/Key pair must be created in PEM-encoded format and should exist in the path folder before running the above command.

Below is the YAML for a Secured Route using Edge Termination:

apiVersion: route.openshift.io/v1
                    kind: Route
                    metadata:
                      name: route-edge-secured                         (1)
                    spec:
                      host: www.example.com                            
                      to:
                        kind: Service
                        name: route-edge-secured                            
                      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 field is used for naming the object and has a limit of 63 characters.
  2. The termination field is edge for edge termination.
  3. The key field is where the contents of the PEM key are entered.
  4. The certificate field is for the contents of the certificate in PEM format.
  5. caCertificate is optional but it may be required to enter the CA (Certificate Authority) cert for successful authentication.

insecureEdgeTerminationPolicy is the attribute used to configure what happens with this type of traffic. The three values representing the goal discussed above are None or empty, Allow or Redirect.

Below is the YAML for A Secured Route using Edge Termination allowing HTTP Traffic:

apiVersion: route.openshift.io/v1
                    kind: Route
                    metadata:
                      name: route-edge-secured-allow-insecure         (1)
                    spec:
                      host: www.example.com                                 
                      to:
                        kind: Service
                        name: service-name 
                      tls:
                        termination: edge                             (2) 
                        insecureEdgeTerminationPolicy: Allow          (3)
                        [ ... ]
                    
  1. The name field is used for naming the object and has a limit of 63 characters.
  2. The termination field is edge for Edge Termination.
  3. insecureEdgeTerminationPolicy field is used to configure what happens with the insecure traffic. In the example YAML file above, insecure traffic is allowed.

Below is the YAML for a Secured Route Using Edge Termination redirecting HTTP traffic to HTTPS:

apiVersion: route.openshift.io/v1
                    kind: Route
                    metadata:
                      name: route-edge-secured-redirect-insecure      (1)
                    spec:
                      host: www.example.com
                      to:
                        kind: Service
                        name: service-name  
                      tls:
                        Termination: edge                             (2)                            
                        insecureEdgeTerminationPolicy: Redirect       (3) 
                        [ ... ]
                    
  1. The name field is used for naming the object and has a limit of 63 characters.
  2. The termination field is edge for Edge Termination.
  3. insecureEdgeTerminationPolicy field is used to configure what happens with the insecure traffic. In the example YAML file above, insecure traffic is Redirected to HTTPS.

Identify under/over-provisioned K8s resources and use Terraform to auto-optimize

WATCH 3-MIN VIDEO

Passthrough Termination

In Passthrough Termination, the termination is passed on from the router straight to the pod. The pod is then responsible for providing the certificate and decrypting the traffic. Since termination is not happening on the router, certificates are not part of the route.

Passthrough Termination provides end-to-end encryption. This is the only type of termination that requires the client to have a certificate. It is also known as "two-way authentication”. The screenshot below shows how to configure Passthrough Termination using GUI.

The following command is used to create a Secure Route with Edge Termination

Even though Passthrough Termination is being used, there is still an option for “Insecure traffic”. The only options available for “Insecure traffic” when using Passthrough termination are “empty” or “redirect”. There is no option to add the certificate because the Pod provides the certificate for Passthrough Termination.

The following command is used to create passthrough termination:

$oc create route passthrough route-passthrough --service=service-name --port=1234

Below is the YAML for a Secured Route using Passthrough Termination:

apiVersion: route.openshift.io/v1
                    kind: Route
                    metadata:
                      name: route-passthrough                 (1)
                    spec:
                      host: www.example.com
                      Port:
                        targetPort: 1234  
                      to:
                        kind: Service
                        name: service-name 
                      tls:
                        termination: passthrough              (2)                                                  
                
  1. The name field is used for naming the object and has a limit of 63 characters.
  2. The termination field is passthrough for Passthrough Termination.

Re-encryption Termination

Re-encryption is Edge Termination with encapsulation. The termination happens at the router the same way it does in Edge Termination. However, instead of forwarding the insecure traffic to the Pod, blocking it, or redirecting it (which can be specified using insecureEdgeTerminationPolicy field), the router re-encrypts the traffic before sending it off to the destination.

The re-encryption certificate can use a different certificate depending on the endpoint requirement. This secures the entire path, even the internal communication

The screenshot below shows how Re-encryption Termination is configured using the OpenShift GUI.

The following command is used to create a Secure Route with Edge Termination

The following command can be used to create a Secured Re-encrypt route

$oc create route reencrypt --service=route-pt-secured --cert=tls.crt --key=tls.key --dest-ca-cert=destca.crt --ca-cert=ca.crt --hostname=www.example.com                               
                

Note: Certificate/Key pair must be created in PEM-encoded format and should exist in the path folder before running the above command.

Below is the YAML for a Secured Route using Re-Encrypt Termination:

apiVersion: v1
                    kind: Route
                    metadata:
                      name: route-pt-secured 
                    spec:
                      host: www.example.com
                      to:
                        kind: Service
                        name: route-pt-secured                           (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-----                                                  
                

Learn the “80-20 rule” applied to Kubernetes optimization

Watch Free Video
  1. The name field is used for naming the object and has a limit of 63 characters.
  2. The termination field is set to reencrypt for Re-encryption Termination.
  3. The destinationCACertificate field specifies the certificate for re-encryption, which will encrypt the traffic leaving the router to the Pod after the initial TLS termination on the router. If this field is left empty, the router will automatically use the certificate generated by the Certificate Authority configured to provide a certificate for this service. This saves the need for adding a certificate for every new path or router.

Since Re-encryption Termination is the same as Edge Termination for the initial TLS termination, its routes will have insecureEdgeTerminationPolicy with all the same values as Edge-Terminated routes.

Basic Troubleshooting of OpenShift Routes and Applications

To help you get started with basic troubleshooting for OpenShift routes and applications, let's assume you have a service configured in a cluster and a user is trying to access this service from outside the cluster. They can’t access the service and you need to figure out why. Below, we’ll walk through some steps to help troubleshoot.

You know there needs to be a process configured to listen on a public IP for any external user attempting to access the service for this to work. A route is also required for the traffic inside the cluster if an attempt to reach the service has been made externally.

The command given below is run on the machine where the issue occurs to determine if the service is running. This is used if the HTTP service is unavailable from outside the cluster.

curl -kv http://link.example.com:8000/bar                               
                    

Next, you should check if DNS is working. Only do this if the previous command returns output suggesting that the service is running internally, but there may b an issue with DNS.

dig +short link.example.com                              
                    

The command above should resolve the given URL to an IP address. This shows that the URL can be resolved externally. If it doesn't resolve, there is an issue with the DNS.

However, if the URL resolves or it starts to resolve after fixing the DNS issue, and the service is still not accessible externally, you should continue troubleshooting. The next step is to telnet to the resolved IP address against the port your service is running on.

telnet10.20.30.40 8000                          
                

The command should result in this output.

Trying 10.20.30.40...
                    Connected to 10.20.30.40                            
                

If the router is not listening on the specified port, it will return the following error.

Trying 10.20.30.40... 
                    telnet: connect to address 10.20.30.40: Connection refused                           
                

Or the following error if there is no service listening on the IP address.

Trying 10.20.30.40... 
                    telnet: connect to address 10.20.30.40: Connection timed out                         
                

In either case, we will then need to troubleshoot the router. You can find information on OpenShift network troubleshooting here.

To check if the application route is working, run the oc get route command. This command lists the running routes in the current namespace. If it gives the output and shows that the route is working, there is no issue in the route.

Route command shows that the route is not working

If the oc get route command shows that the route is not working, then run the command oc describe route "route name" to get a detailed description of the issue. This will help to identify and fix the issue.

That covers the basics of OpenShift route

That covers the basics of OpenShift route and application troubleshooting. For a deeper dive, see the Troubleshooting section of the OpenShift admin guide.

Free Proof of Concept implementation if you run more than 5,000 containers

Request PoC

Conclusion

OpenShift allows different types of routes to be configured depending on the use case. With the ever-growing security challenges, the focus on the Zero Trust security principle is the way forward for organizations. Even though OpenShift allows certain route types to be configured without end-to-end encryption, it is best to keep the environment as secure as possible and use Passthrough and Re-encryption Termination whenever possible.

Like this article?

Subscribe to our LinkedIn Newsletter to receive more educational content

Subscribe now

Discover the benefits of optimized cloud & container resources. Try Densify today!

Request a Demo