Custom Kubernetes Ingress Default Backend and Error Pages
Ken Moini
Posted on May 25, 2020
When you're setting up a Kubernetes cluster, one of the choices you need to make is what Ingress to use - or what combination of Ingresses (Ingressi?) to use.
I've used a number of Ingress Controllers in Kubernetes clusters on different clouds, and they all have their place and reason. The classic choice however, is the now native Ingress option provided by the Kubernetes project, the nginx-ingress controller.
Wait, what is an Ingress?
In the terms of a Kubernetes cluster, an Ingress Controller is a cluster resource that will route traffic into the services in the cluster, from external requests. This is how mycutedogs.com
gets translated and routed to the side-sites/mycutedogs-com
namespace/service in the cluster.
Blank and Bleak
When you deploy the Nginx Ingress Controller, you'll see some very basic error pages such as this:
But instead, what if you could make it look something like this:
How this all works
So when you deploy the Nginx Ingress Controller, it listens on the edge of your Kubernetes cluster for traffic. If it does not have a matching service to route to, it'll throw an error. Those errors are served traditionally from the nginx-ingress-controller container, but you can override where those errors are served from with some modifications to the Deployment and ConfigMap.
In order to set up your own custom error pages you'll need to fork my repo, build your own copy of the container image with your own error HTML files, and do some modifications to the corresponding Deployment Config.
Optional: Modify the error pages
If you'd like to set your own default-backend custom error pages, you'll need to do the following steps - if not and you'd just like to use the more spiffy versions I have available, continue to the Deployment steps
- Fork my repo: https://github.com/kenmoini/custom-nginx-ingress-errors
- Modify the error pages in the
www/
directory as you see fit - Connect to Docker Hub, Quay.io, etc to create your own available image
- Modify the
k8s-deployment.yaml
file in the repo to point to your own image.
Deployment
These instructions assume that you deployed the Ingress Controller in the default ingress-nginx
namespace.
1) Clone down my repo: https://github.com/kenmoini/custom-nginx-ingress-errors
git clone https://github.com/kenmoini/custom-nginx-ingress-errors
cd custom-nginx-ingress-errors
2) Deploy to your Kubernetes cluster - the YAML file already targets the nginx-ingress
namespace:
kubectl apply -f k8s-deployment.yaml
3) Modify the ingress-nginx/ingress-nginx-controller
Deployment and set the value of the --default-backend-service
flag to the namespace/svc-name of the newly created error backend, which should be ingress-nginx/nginx-errors
by default.
export KUBE_EDITOR="nano" # optional, switch to the Nano editor
kubectl edit deployment/ingress-nginx-controller -n ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
[...]
spec:
[...]
template:
spec:
containers:
- args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
- --default-backend-service=$(POD_NAMESPACE)/nginx-errors
[...]
4) Edit the ingress-nginx/nginx-configuration
ConfigMap and add the key:value pair of "custom-http-errors": "404,500,503"
:
kubectl edit cm/nginx-configuration -n ingress-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
[...]
data:
custom-http-errors: "404,500,503"
5) Test your new error pages by navigating to the Ingress Load Balancer:
$ kc get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.245.31.157 173.28.135.40 80:32563/TCP,443:30965/TCP 18d
nginx-errors ClusterIP 10.245.17.217 <none> 80/TCP 117m
$ curl -sS http://173.28.135.40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Error 404</title>
[...]
Bonus: Docker Hub Pre-Push Hook
This repo also has an extra file in hooks/pre-hook
which creates another tag with the Git repo commit - it's pretty neat!
Posted on May 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.