Ingress Controller - simplified routing in Kubernetes
In our previous articles, we set up a Kubernetes cluster running the application seen on Fig. 1. One of the problems we had was the hardcoded IP of the Web Application in the Frontend, which enabled the frontend to send requests to the backend for sentiment analysis, but requires us to always rebuild the application to change the IP. Although currently maintainable when we add different environments (development, staging, production), and with time as the project grows the more services are added, keeping this in the code is error-prone, not obvious and requires uselessly additional effort.
The Ingress Controller solves the above problem and in combination with Ingress Rules enables us with one single IP to configure routing of requests to multiple services.
In this article, we will delve deeper into the Ingress Controller but before we do so we need to fulfil the prerequisites below:
1. Have a Kubernetes cluster up and running
To follow up with this guide we recommend the Azure Kubernetes Service (AKS) or Minikube, though the same concepts work on all correct Kubernetes Implementations.
2. Install Helm
Because the Ingress Controller is made up of several components, instead of installing the components separately we can by using Helm, reduce the complexity to one parametrized command for the whole installation.
To install Helm on your computer follow the official docummentation.
After installing Helm ensure that you are connected to your Kubernetes Cluster `kubectl cluster-info` and execute the following command:
This command puts the Kubernetes cluster in communication with the Helm client in our computer, enabling it to manage package installations.
3. Install the Ingress Nginx Package
helm install stable/nginx-ingress --name routing --namespace kube-system --set rbac.create=false
This installs all the required components for Ingress Controller to work on your cluster. Verify the installation by running:
kubectl get pods -n kube-system -w
You should find two pods starting with routing-nginx-ingress-controller and routing-nginx-ingress-default-backend being in ContainerCreating state. Wait until they are in Running state and continue with the next part.
Ingress Controller is up and ready, now we must configure to route to the correct services. Before we get into the resource configuration let’s think of the outcome we want:
- When the clients request the base domain we want to return the React Application. (i.e. on the base path forward the request to the sa-frontend service)
- Requests containing the path /sentiment should be forwarded to the sa-web-app. (see the file SentimentController.java for the implementation)
We diagram out the solution:
With a clear goal, we only need to configure the Ingress Controller by creating the Ingress Rules in the next section.
Configuring the SA-Frontend Ingress rule.
Let’s rephrase what we want to achieve “on the base path, route to the sa-frontend service”. Without further ado let’s see the Ingress rule configuration:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: sa-ingress-frontend annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" # 1 spec: rules: - http: paths: - path: / backend: serviceName: sa-frontend # 2 servicePort: 80 # 3
We will put this together in the last section, initially let’s understand the simplicity of configuring routes.
- ssl-redirect: Avoid being redirected to HTTPS
- serviceName: Name of the service to be forwarded
- servicePort: Port in which the call should be forwarded
Configuring the SA Web App Ingress rule
Rephrase of our goal “on the path /sentiment route requests to the sa-web-app service”:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: sa-ingress-web-app annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" spec: rules: - http: paths: - path: /sentiment backend: serviceName: sa-web-app servicePort: 80
And we are ready!
Running the Application
To get the application up and running clone the repository k8s-mastery and checkout the branch ingress-controller, this branch contains the ingress rules defined in the folder resource-manifests.
Navigate to the folder: resource-manifests and execute the below command to create all the resources present in this folder.
$ kubectl apply -f . ingress.extensions "sa-ingress-frontend" created ingress.extensions "sa-ingress-web-app" created deployment.extensions "sa-frontend" created deployment.extensions "sa-logic" created deployment.extensions "sa-web-app" created service "sa-frontend" created service "sa-logic" created service "sa-web-app" created
With the resources created we are ready to give the application a try, get the Ingress Public IP by executing the below command:
$ kubectl get svc -n kube-system NAME EXTERNAL-IP AGE routing-nginx-ingress-controller 42.91.281.70 2h routing-nginx-ingress-default-backend <none> 2h
Open the web browser and navigate to the external ip. The app should be functional and the routes working!
For more articles about Kubernetes we recommend: