How to custom your default backend on Kubernetes NGINX controller

Valentin Lgrs
alter way
Published in
4 min readApr 15, 2020

In this article we will see how to deploy a custom default backend in a NGINX Ingress controller with Helm on a Kubernetes cluster.

What is NGINX Ingress controller?

The NGINX Ingress Controller for Kubernetes provides enterprise‑grade delivery services for Kubernetes applications. With the NGINX Ingress Controller for Kubernetes, you get basic load balancing, SSL/TLS termination, support for URI rewrites, and upstream SSL/TLS encryption.

What is a default backend?

The default backend is a service which handles all URL paths and hosts the NGINX controller doesn’t understand.

Requirement

  • A Kubernetes cluster (1.6+)
  • Helm (3.0+)
  • Docker and a container registry (for the custom backend docker image)

Source

The code used in this article is available in a GitHub repository : https://github.com/vlgrs/custom-default-backend

$ git clone https://github.com/vlgrs/custom-default-backend.git

Build custom default backend Docker image

First we need to build a docker image to use it as custom default backend in the NGINX Ingress controller Helm chart.

I decided to use a very simple image based on nginx:alpine docker image, and put a custom index.html file in /usr/share/nginx/html

Once the repository cloned, you can build the image by running :

$ docker build -t <your-registry>/custom-default-backend:1.0 ./backend-docker-image/

For the purpose of this article, i used a Azure private container registry to host my custom default backend docker image.

Learn how to create an Azure Private Registry here

Learn how to connect Azure Private Registry with your Kubernetes cluster here

Once the image built, push it to your private registry :

$ docker push <your-registry>/custom-default-backend:1.0

The docker image is now ready to use.

Deploy the custom default backend

Before deploying our NGINX Ingress controller with Helm, we need to create the Kubernetes resources (Namespace, Service & Deployment) to be used by the Ingress controller.

In the default-backend.yaml file, you need to replace the image used in the Deployment spec to use your own custom backend docker image :

$ vi custom-default-backend/ingress-controller/default-backend.yaml#Replace the registry image value    
spec:
containers:
- name: nginx-custom-default-backend
image: <your-registry>/custom-default-backend:1.0

Save and then apply it on the Kubernetes cluster :

$ kubectl apply -f custom-default-backend/ingress-controller/default-backend.yaml

It will create a new Kubernetes namespace for our resources, a new Kubernetes service with the rights NGINX labels to be used by the Ingress controller, and a deployment with our custom default backend docker image.

The custom default backend is ready to use.

Deploy the NGINX Ingress controller with Helm

Once Helm installed, we need to add the stable chart provided in the Helm chart stable repository :

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/

We also need to modify configuration of the values.yaml file used to deploy our NGINX Ingress controller :

$ vi custom-default-backend/ingress-controller/values.yaml# In the controller section, add the name of default backend servicecontroller:
...
## Required only if defaultBackend.enabled = false
## Must be <namespace>/<service_name>
##
defaultBackendService: "ingress-backend-demo/nginx-custom-default-backend"
# In the defaultBackend section, turn the enable value to "false"
defaultBackend:
...
## If false, controller.defaultBackendService must be provided
##
enabled: false

Now deploy the NGINX Ingress controller :

$ helm install --namespace ingress-backend-demo ingress-controller-demo stable/nginx-ingress -f custom-default-backend/ingress-controller/values.yaml

Wait for the deployment to go into running state, it should provide you a public IP address (according to your cluster configuration) that you can obtain by running this command :

$ kubectl get service --namespace ingress-backend-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-controller-demo LoadBalancer 172.16.221.249 <your-public-ip> 80:31697/TCP,443:31329/TCP 59d
nginx-custom-default-backend ClusterIP 172.16.55.245 <none> 80/TCP 59d

If you go to the address http://<your-public-ip> you should land on your custom backend page.

Well done ! We have customized the default backend on a Kubernetes cluster !

Go even further

This is a very basic configuration of a customized default backend, and it will not handle the know error URLs (like 404, 503…). If you want to customize those pages, i recommend you to check this Tutorial where it’s nicely explain.

References

NGINX Ingress controller : https://www.nginx.com/products/nginx/kubernetes-ingress-controller/
Default backend : https://kubernetes.github.io/ingress-nginx/user-guide/default-backend/
Azure Container Registry : https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-azure-cli
https://docs.microsoft.com/en-us/azure/aks/cluster-container-registry-integration

--

--

Valentin Lgrs
alter way

Cloud consultant working on AWS, Azure and Kubernetes stuff.