Testing the NGINX Ingress Controller locally (Docker Desktop)

Testing the NGINX Ingress Controller locally (Docker Desktop)

In this post, we will explore (briefly) the Ingress in Kubernetes and see how to traffic multiple host names at the same IP address (localhost).

What is Ingress?

Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.

Ingress.png

To use Ingress, you will need to install an Ingress Controller. There are many available, all of which have different features:

Today, we will use the NGINX Ingress Controller.

Prerequisites

Installation

One of the easiest ways to install the NGINX Ingress Controller is to use Helm(if you are new to Helm, please check this post). Run the following commands:

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

Run kubectl get ingressclass and kubectl get services to check the installation:

NAME    CONTROLLER                     PARAMETERS   AGE
nginx   k8s.io/ingress-nginx           <none>       15h
NAME                                               TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
nginx-ingress-ingress-nginx-controller             LoadBalancer   10.99.137.48     localhost     80:32600/TCP,443:30560/TCP   15h
nginx-ingress-ingress-nginx-controller-admission   ClusterIP      10.102.232.211   <none>        443/TCP                      15h

Open http://localhost/ in your browser:

image.png

Using Ingress to expose Services

Let's create a deployment.yml file with the following content:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api-container
          image: nginx
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

A service.yml file as follows:

apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: api

And the ingress.yml file, to route every request to www.api.com to the api-service:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: www.api.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

Run kubectl get ingress:

NAME                                                CLASS   HOSTS                                            ADDRESS     PORTS   AGE
api-ingress                                         nginx   www.api.com                                      localhost   80      8h

Everything looks fine, but if we type http://www.api.com/ in a browser, we will not be able to reach our service. That happens because nothing tells the browser to resolve that URL to our localhost. Let's change that, open the C:\Windows\System32\drivers\etc\hosts file and add 127.0.0.1 www.api.com at the end:

192.168.1.105 host.docker.internal
192.168.1.105 gateway.docker.internal
127.0.0.1 kubernetes.docker.internal
127.0.0.1 www.api.com

Open http://www.api.com/ in your browser:

image.png

And that's all. Thanks, and happy coding.