Kubernetes Ingress with NGINX
By: François Fernandès
Tags: Nginx, Ingress, Ingress Controller, Kubernetes, DevOps

Let’s assume that a service named frontend-svc should be made available under the domain sample-service.example.com . This would require an Ingress resource definition like the following:

At the first glance, the example above might seem relatively complex. But once you understand the structure of the Ingress resource, it is very simple. Let’s split the example into smaller sections:

Header (Lines 1–4)

This is the common header for all Kubernetes resources. It identifies the resource as kind: Ingress and some metadata.

Rules (Lines 6 & 7)

This is the actual core of the Ingress definition. This section defines how incoming requests shall be mapped, based on the requested hostname. In our example, the Ingress definition targets the hostname sample-service.example.com .

Path Mapping (Lines 9–13)

The path mapping specifies how request paths shall be mapped to the actual backends. Backends are Services, deployed in the cluster, identified by their name and a port.

An Ingress definition might even consist of multiple rules and rules with multiple paths. Let’s pretend, that we would like to expose the REST API, that the frontend is based on, under /api , backed by the service backend-svc on port 8081 :

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

name: digitalfrontiers-sample-ingress

spec:

rules:

- host: sample-service.example.com

http:

paths:

- path: /

backend:

serviceName: frontend-svc

servicePort: 80

- path: /api

backend:

serviceName: backend-svc

servicePort: 8081

This Ingress definition will route requests on /api to http://backend-svc:8081/api . It is important to note, that the full path will be preserved by default. Given path mapping with path: /api/v1/resources/ and a request for /api/v1/resources/ab0394a , will result in a call with the full path ( /api/v1/resources/ab0394a ) on the backend.

Unlike other resources, Kubernetes has no built-in support for Ingresses. This might sound strange, considering I described Ingress as a Kubernetes native resource. The Ingress is just a description of how routing should be performed. The actual logic has to be performed by an “Ingress Controller”.

Ingress Controller

The Ingress is the definition of how the routing should be done. But the execution of those rules has to be performed by an “Ingress Controller”. Due to this, creating Ingress resources in a Kubernetes cluster won’t have any effect until an Ingress Controller is available.

The Ingress Controller is responsible of routing requests to the appropriate services within the Kubernetes cluster. How an Ingress Controller executes this task, is not explicitly defined by Kubernetes. Thus an Ingress Controller can handle requests in a way that works best for the cluster.

The Ingress Controller is responsible to monitor the Kubernetes cluster for any new Ingress resources. Based on the Ingress resource, the Ingress Controller will setup the required infrastructure to route requests accordingly.

NGINX Ingress Controller

Further on, we’ll focus on the NGINX Ingress Controller, being an Ingress Controller implementation based on the popular NGINX http-engine. Although there are many different Ingress Controller implementations, the NGINX based implementation seems to be the most commonly used one. It is a general purpose implementation that is compatible with most Kubernetes cluster deployments.