K8s Ingress vs. OpenShift Route
Tags: kubernetes, openshift, network
Published: 2021-03-26 00:07:17

> *This article aims to clear some confusion between Ingress and Route, and hopefully enable you to take advantage of the power of both.*

Recently starting to deal with OpenShift clusters, I found most of the resource types in OCP are the native K8s resources I’m familiar with. Most of them, except for *Route*.

## Ingress

[Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) is the native API object K8s defined to enable external access into services in the cluster.

It is THE resource type people usually expect to see in AKS, GKE, EKS, or in-house K8s installations when they connect their service to the vast internet.

A bare Ingress resource YAML manifest is like an interface, where the actual behavior heavily depends on how it is provisioned in your cluster - more specifically, the [Ingress Conroller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) backing it.

For example, if your cluster uses [ALB to back your Ingress](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) (which is the most-likely case for AWS EKS), you will need some alb-specific annotations like this as part of the [official example](https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.1.3/docs/examples/2048/2048_full.yaml):
```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: IP
```

Normally when you try to use Ingress you would want to:
1. Find the Ingress Controller installed in your cluster.
2. If none-installed, [look up](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) one that's supported by your cloud provider (including private/hybrid) and install it.
3. Add the annotation based on the manual of that controller.

## Route
[Route](https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html), on the other hand, is not a native K8s thing, it only exists in the OpenShift world.

It depends on another Openshift concept - Router. Consider Router as plugins deployed on your cluster *nodes* that enables configurable routings. By routings, I mean traffic from external clients to in-cluster application services.

Note that a Router is installed on a node, so to reach the Router you need to reach the node first.

For example, if an [HAProxy Router](https://docs.openshift.com/container-platform/3.11/architecture/networking/assembly_available_router_plugins.html#architecture-haproxy-router) is used, external traffic is expected to go to the particular node hosting the HAProxy, then being routed to the service/pod.

According to the [dev guide](https://docs.openshift.com/container-platform/3.11/dev_guide/routes.html), there are 3 ways to create a Route.

1. The Openshift web console UI
2. `oc` CLI, such as `oc expose svc/frontend --hostname=www.example.com`
3. YAML manifest, such as
```
apiVersion: v1
kind: Route
metadata:
  name: frontend
spec:
  host: www.example.com
  path: "/test" 
  to:
    kind: Service
    name: frontend
```

Like Ingress, Route also supports annotations, for example `router.openshift.io/cookie_name="my_cookie"`. But note that the annotations have different prefixes than those of Ingress resources, thus their annotations are not interchangeable.

However, the main method to control the behavior of a Route,  rather than through annotations, is by changing the [Router Environment Variables](https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#env-variables).

## Ingress to Route
Starting from Openshift 3.10, [Ingress objects created in Openshift can be translated into Route objects](https://www.openshift.com/blog/kubernetes-ingress-vs-openshift-route).

If you know the difference between Ingress and routes well, this is very convenient.

On the other hand, however, it can easily mislead people trying to take advantage of this translation.

As described in the section above, Routes:
1. Doesn't respect Ingress annotations. *As a result, your fine-tuned annotations on your Ingress manifest file would NOT affect the true behavior of the created Route.*
2. Needs traffic to first reach the node. *So you will need to configure DNS records to Router nodes separately.*

According to the [dev guide](https://docs.openshift.com/container-platform/3.11/dev_guide/routes.html):
> DNS resolution for a host name is handled separately from routing; your administrator may have configured a cloud domain that will always correctly resolve to the OpenShift Container Platform router, or if using an unrelated host name you may need to modify its DNS records independently to resolve to the router.

This has to be taken into consideration and worked upon with the cluster admin for anyone familiar with K8s Ingress but not Openshift Route.