Skip to main content

Nginx Ingress Controller

Ingress Nginx is the well known Nginx http server, packaged to serve as a Kubernetes ingress controller.

It is the most used ingress controller in the Kubernetes ecosystem. In essence, it creates virtual host entries dynamically based on the Ingress resource definitions in your cluster.

info

If you don't know what an Ingress is, you can get up to speed in the kubernetes documentation.

Upstream Kubernetes does not have an ingress controller by default. No matter how many Ingress resources you define, there is nothing in the cluster that manages external access to the services in the cluster.

Even though cloud providers provide a default ingress controller in the cluster, it usually spins up a cloud load balancer component for every Ingress resource you have. This is an expensive default solution to have, given that most clouds price their load balancers around USD 30.

To utilize an open-source ingress controller, make sure to install the Ingress Nginx component, and use the nginx ingress class in your Ingress resources. With this controller, there will be a single cloud load balancer created - saving you a ton of money.

Basic features

Once you installed the Ingress Nginx controller, you can create an Ingress resource to expose an existing application.

Make sure to annotate the resource with kubernetes.io/ingress.class: nginx, so that the controller knows that it has to handle the defined routes. Without the annotation, the default ingress controller of the cluster would handle your ingress, spinning up a cloud load balancer for each ingress.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: infrastructure
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: "my-app.mycompany.com"
http:
paths:
- path: "/"
pathType: "Prefix"
backend:
service:
name: my-app
port:
number: 80

Day-two operations

Updating the ingress controller

Since the ingress controller routes all traffic to your applications, you should always make it highly available (HA) in your setup.

You can achieve this by running multiple replicas of the controller. I typically go with three.

The Ingress Nginx project is equipped with a leader election logic, so it is perfectly capable of running in multiple replicas.

Moving Ingress resources between namespaces

If you outgrow your namespace setup, it may become necessary to move resources to a new namespace.

While you can replicate Deployment and Service resources in an other namespace, you might feel cautious replicating your Ingress. After all, there is only one central controller that handles Ingress resources, and it would be reasonable to think that replicating it could cause problems.

But the truth is, it is completely safe to replicate your Ingress resource to a new namespace. One of the ingresses will take precedence, so as long as you have two identical versions deployed in the two namespaces, you are safe.

Here are the steps to replicate it:

  • Deploy an identical configuration to the new namespace. Deployment, Service, Configmap resources included.
  • Verify that the replicated deployment is up and running
  • Check via the application logs which instance is getting traffic
  • Drop the old Ingress resource
  • Verify that the replicated deployment is getting the traffic now
  • Drop the old Deployment and Service resources from the old namespace

Moving Ingress resources between clusters

Moving Ingress resources between clusters is a matter of DNS record updates.

Here are the steps to replicate it:

  • Deploy an identical configuration to the new cluster. Deployment, Service, Configmap resources included.
  • Verify that the replicated deployment is up and running
  • Update the DNS record of the Ingress domain to point to the ingress controller IP of the new cluster
  • Check via the application logs which replicated instance is getting traffic
  • Monitor the traffic on the old deployment. It may take a few days until traffic fully stops flowing to the old setup. DNS changes take time.
  • Drop the old Ingress resource
  • Drop the old Deployment and Service resources from the old cluster