Imagine you have a beautiful front entrance to your restaurant where customers come in. They walk through this main entrance to reach different parts of your restaurant, such as the dining area or the bar. This entrance is like your “ingress.”
In Kubernetes, an Ingress is like that front entrance. It helps manage external access to the Services inside your cluster. Instead of exposing each Service individually, you can use an Ingress to decide how people from the outside can reach different parts of your application.
In simple terms, a Kubernetes Service is like a central delivery point for your application’s different parts, and an Ingress is like a front entrance that helps people from the outside find and access those parts easily.
Ingress resources act as reverse proxies into Kubernetes. You don’t need a load balancer for every application you run within your estate, as load balancers normally forward traffic and don’t require high levels of computing power. Therefore, spinning up a load balancer for everything does not make sense.
Therefore, Kubernetes provides a way of routing external traffic into your cluster viaIngress resources. These resources help you subdivide traffic according to multiple conditions. Some of these are set out here:
• Based on the URL path
• Based on the hostname
• A combination of the two
The following diagram illustrates how Ingress resources work:
Figure 6.5 – Kubernetes Ingress resources
Ingress resources require an ingress controller to work. While most cloud providers have a controller installed, you must install an ingress controller on-premises or in a self-managed Kubernetes cluster. For more details on installing an ingress controller, refer to https://kubernetes.io/docs/ concepts/services-networking/ingress-controllers/. You can install more than one ingress controller, but you will have to annotate your manifests to denote explicitly which controller the Ingress resource should use.
For this chapter, we will use the nginx ingress controller (https://github.com/kubernetes/ ingress-nginx), which is actively maintained by the Kubernetes open source community. The reason we use this instead of the native GKE ingress controller is that we want to make our setup as cloud-agnostic as possible. The nginx ingress controller is also feature-packed and runs the same irrespective of the environment. So, if we want to migrate to another cloud provider, we will retain all the features we had with Ingress resources before and do an exact like-for-like migration.
To understand how the nginx ingress controller works on GKE (or any other cloud), let’s look at the following diagram:
Figure 6.6 – nginx ingress controller on GKE
The client connects to the Ingress resource via an ingress-managed load balancer, and the traffic moves to the ingress controllers that act as the load balancer’s backend. The ingress controllers then route the traffic to the correctService resource via routing rules defined on the Ingress resource.
Now, let’s go ahead and install the nginx ingress controller using the following command:
$ kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/ingress-nginx\/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml
This will boot up several resources under theingress-nginx namespace. Most notable is the ingress-nginx-controller Deployment, which is exposed via the ingress-nginx-controller LoadBalancer Service.
Let’s now expose the flask-app Service via an Ingress resource, but before we do that, we will have to expose the flask-app Service on a ClusterIP instead, so let’s apply the relevant manifest using the following command:
$ kubectl apply -f flask-clusterip.yaml
The next step is to define an Ingress resource. Remember that as GKE is running on a public cloud, it has the ingress controllers installed and running. So, we can simply go and create an ingress manifest—flask-basic-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: flask-app
annotations:
kubernetes.io/ingress.class: “nginx”
spec:
defaultBackend:
service:
name: flask-app
port:
number: 5000
This resource defines a default backend that passes all traffic to theflask-app pod, so it is counter-productive, but let’s look at it for simplicity.
Apply the manifest using the following command:
$ kubectl apply -f flask-basic-ingress.yaml
Now, let’s list the Ingress resources using the following command:
$ kubectl get ingress flask-app
NAME
CLASS
HOSTS
ADDRESS
PORTS
AGE
flask-app
*
80
40s
We can see that the flask-app Ingress resource is now listed with HOSTS *. That means that this would listen on all hosts on all addresses. So, anything that does not match other Ingress rules will be routed here. As mentioned, we need the nginx-ingress-controller Service external IP address to invoke all Services exposed via Ingress. To get the external IP of the nginx-ingress-controller Service, run the following command:
$ kubectl get svc ingress-nginx-controller -n ingress-nginx
NAME TYPE EXTERNAL-IP
ingress-nginx-controller LoadBalancer 34.120.27.34
We see an external IP allocated to it, which we will use further.