Introduction to NGINX


What is ingress?

Ingress is like the main door in the building with signs that tells you which room to go to.

This is more clear in the context of the cluster. Lets say in our kubernetes cluster, we have many applications hosted, like a blog, a ecommerce store and a portfolio site. Any incoming request needs to be redirected to the right application. Ingress is what performs this task.

NGINX is the application that enforces the ingress. In the building analogy, NGINX is the security guard in the building that looks at the incoming request and directs them to the right room based on the ingress rules.


Usage

Following use cases:


Hands On: Kubernetes Cluster

Install Minikube

Let us first set up a simple kubernetes cluster to demonstrate the use of nginx ingress controller.

In a linux machine, run the following commands to install minikube:

Create a kube cluster

Let us create a simple kube cluster. Since we do not want to create any VMs, let us use --driver=none option to start minikube.

minikube start --driver=none --container-runtime=containerd


If the minikube command runs correctly, it will install kubectl and point the config to the local cluster so that we can use kubectl command.

minikube kubectl -- get nodes -A -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME vmname Ready control-plane 5m35s v1.32.0 <ip> Ubuntu 22.04.4 LTS 5.15.0-1058-ibm containerd://1.7.24

At this point, basic kube control plane pods are running in the cluster.

Deploy NGINX

Let us deploy NGINX ingress controller in our cluster. We will use help for this purpose, which is a package manager for kubernetes.

Let us first download helm:

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

The above command will add help into the binary location, so helm should be readily usable now.

Then, let us download and install nginx ingress in our cluster.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install nginx-ingress ingress-nginx/ingress-nginx

If we check the current running pods, we should see following:

# minikube kubectl -- get po -A NAMESPACE NAME READY STATUS RESTARTS AGE default nginx-ingress-ingress-nginx-controller-78d94b756c-r4gzt 1/1 Running 0 59s


Running Our Apps with Exposed Ports

Here, we will run two applications each of which will have port 80 exposed. For the sake of ease, we will run a simple nginx container and expose their port 80.

To expose the port, we will create a SERVICE type object along with the deployment of the application.

Our first application definition and service definition in file app1.yaml.

# cat app1.yaml apiVersion: apps/v1 kind: Deployment metadata: name: app1 spec: replicas: 1 selector: matchLabels: app: app1 template: metadata: labels: app: app1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: app1-service spec: selector: app: app1 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP

Our second application, which is basically the copy of the first application but with a different name.

apiVersion: apps/v1 kind: Deployment metadata: name: app2 spec: replicas: 1 selector: matchLabels: app: app2 template: metadata: labels: app: app2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: app2-service spec: selector: app: app2 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP

Let us apply the yaml files so that apps are created.

# minikube kubectl -- apply -f app1.yaml deployment.apps/app1 created service/app1-service created # minikube kubectl -- apply -f app2.yaml deployment.apps/app2 created service/app2-service created

Create INGRESS object to direct request

At this point, we have created applications with exposed ports. But if any external requests are to access the applications, we need to define some rules so that the requests are properly routed. Going back to the building analogy, we need to create the sign at the door to tell which room to go to.

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-app-ingress spec: rules: - host: app1.local http: paths: - path: / pathType: Prefix backend: service: name: app1-service port: number: 80 - host: app2.local http: paths: - path: / pathType: Prefix backend: service: name: app2-service port: number: 80

The above ingress object routes any requests coming to app1.local to app1-service port number 80, which in turn routes it to our application 1. Similar is the case for app2.

Apply the yaml file for ingress object above similar to how we applied for deployment creation in earlier section.

Update /etc/hosts

Just so that our requests are properly decoded by our local DNS server, we should add following entries into our /etc/hosts file.

127.0.0.1 app1.local 127.0.0.1 app2.local