How to use Ingress Objects on OpenShift
Does OpenShift support Ingress objects? Yes! In recent versions of OpenShift (since 3.10), you can use Ingress objects to expose apps outside the cluster. In this article you’ll see how.
If you’ve landed on this page, it’s probably because you want to use Ingress objects on OpenShift.
Just in case you’re not familiar with what they are, here’s a super-quick look at what an Ingress is, and whether you need one. Then we’ll look at an example.
Ingress to impress, or Route to loot?
From Kubernetes to OpenShift… what’s a Route?
Routes are an OpenShift-specific way of exposing a Service outside the cluster.
A Route is basically a piece of configuration that tells OpenShift’s load balancer component (usually HAProxy) to create a URL and forward traffic to your Pods.
It also has a funky default behaviour that lets you create a Route with just a name only, and OpenShift will generate a URL for you. e.g. If you create a route called fish
in the namespace fishtank
, it will usually try to create a URL fish-fishtank.youropenshiftcluster.com
From OpenShift to Kubernetes… what’s an Ingress?
Ingress objects are like the upstream equivalent of Routes. They aren’t tied to OpenShift.
They behave differently in different Kubernetes clusters, depending on which ingress controller you’re using, and where the Kubernetes cluster is located.
For example, if you create an Ingress on an Amazon EKS cluster, Amazon will configure an Application Load Balancer (ALB) for you, behind the scenes. But if you create an Ingress object on a Google Kubernetes Engine (GKE) cluster, Google will configure a Google Cloud Load Balancer.
Do you need an Ingress?
If I’m only going to deploy on OpenShift then I will just stick with Routes.
But, if I’m developing an app that will be deployed onto OpenShift and Kubernetes, and I’m also developing all of the Kubernetes manifests and Helm charts, then I might use Ingress objects.
Using Ingress means that your app’s manifests are potentially more portable between different Kubernetes clusters. So if you’re creating a Helm chart with Ingress objects in it, you can run helm install
against an OpenShift or vanilla Kubernetes cluster, and it should just….work. “Should.”
So if you’re creating an app for public consumption, you might want to think about using Ingress objects in your Helm charts or Kustomize templates!
Example: Exposing an app with an Ingress on OpenShift
To see Ingress working on OpenShift, I’ll show you how I exposed an app to the outside world with an Ingress object on OpenShift 4.7.
First, I create a new Project:
oc new-project toms-ingress
Next, deploy an app. I like to use the hello-openshift image on Docker Hub, because it just displays a simple Hello message on HTTP port 8080, which is kinda similar to how an API would work:
oc new-app openshift/hello-openshift
This should create a bunch of objects like these:
--> Creating resources ...
imagestreamtag.image.openshift.io "hello-openshift:latest" created
deployment.apps "hello-openshift" created
service "hello-openshift" created
--> Success
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/hello-openshift'
Run 'oc status' to view your app.
Create the Ingress
Now, normally, to expose the Service you would create a Route here.
But instead, try creating an Ingress object, which forwards to the Service. Make sure you change the host
field to a URL which can be handled by your OpenShift cluster:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-openshift
spec:
rules:
- host: hello-openshift.yourcluster.example.com
http:
paths:
- backend:
# Forward to a Service called 'hello-openshift'
service:
name: hello-openshift
port:
number: 8080
path: /
pathType: Exact
You can put this YAML into a file and then apply it to the cluster with oc apply -f ingress.yaml
.
Now we can see that 1 x Ingress was created:
$ oc get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-openshift <none> hello-openshift.apps.ocp1.example.com apps.ocp1.example.com 80 15s
…. and OpenShift has also created a Route. It’s auto-generated, so notice the weird random characters at the end of the name:
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
hello-openshift-5cbw4 hello-openshift.apps.ocp1.example.com / hello-openshift 8080-tcp None
Now I can access my application:
$ curl hello-openshift.apps.ocp1.example.com
Hello OpenShift!
Let’s try deleting the Route
Let’s simulate a cat walking across the keyboard, and deleting the Route:
oc delete route hello-openshift-5cbw4
Then if we run oc get routes
again, you’ll see a new Route gets created again, immediately:
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
hello-openshift-76tlh hello-openshift.apps.ocp1.example.com / hello-openshift 8080-tcp None
This is because OpenShift ensures there’s always a Route to match a valid Ingress object.
Now let’s delete the Ingress using --all
- this will delete all Ingress objects in this project:
oc delete ingress --all
The ingress controller notices that the Ingress has gone, and deletes the Route. When we run oc get route
, it returns nothing:
$ oc get route
No resources found in toms-ingress namespace.
TL;DR
-
You can create an Ingress object in OpenShift with a valid
host
field -
OpenShift will notice it, and create a Route for you.
-
You can access the application via your chosen URL.
One important thing to note: I don’t think that the Ingress object can automatically “guess” the routing suffix of your cluster (the bit like .apps.youropenshift.com
). So you’ll need to give the full URL when you create the Ingress in the host field.
Thanks for reading!