To update the default error page, edit the config map of nginx-ingress-controller. Insert a new key custom-http-errors with the HTTP status code that you want to change its error page, such as:
apiVersion: v1
kind: ConfigMap
data:
custom-http-errors: 404,413,503
enable-vts-status: "false"
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.6.0
component: controller
heritage: Tiller
release: nginx-ingress
name: nginx-ingress-controller
namespace: Nginx
Now, fire the test command again,
curl -i "[http://err-test.192.168.64.5.nip.io/err?code=413](http://err-test.192.168.64.5.nip.io/err?code=413)"
HTTP/1.1 404 Not Found
Server: nginx/1.15.10
Date: Sun, 05 May 2019 11:36:04 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 21
Connection: closedefault backend - 404
This is NOT what you want. The Nginx ingress controller correctly captures the HTTP status code that we want to customize. However, the default Nginx “default-backend” (Image: k8s.gcr.io/defaultbackend:1.4) just simply returns 404 status regardless of the actual status code that the application intends to return. This will cause a problem if the status code is to be used for other purposes.
In the Nginx Ingress Controller documentation you may see:
The custom backend is expected to return the correct HTTP status code
instead of 200. NGINX does not change the response from the custom
default backend.
Then in Dockerfile you have to add path to your defined custom backends errors:
ADD custom-error-pages /
CMD ["/custom-error-pages"]
Build the image and push into docker hub. Redeploy the Nginx helm chart in K3s it looks like:
apiVersion: k3s.cattle.io/v1
kind: HelmChart
metadata:
name: nginx-ingress
namespace: Nginx
spec:
chart: stable/nginx-ingress
targetNamespace: kube-system
valuesContent: |-
defaultBackend:
enabled: true
name: default-backend
image:
repository: your-image/custom-error-page
tag: latest
In k8s simply execute:
helm upgrade nginx-ingress stable/nginx-ingress --set defaultBackendService.enabled=true --set defaultBackend.image.repository=your-image/custom-error-page --set defaultBackend.image.tag=latest
Then test again, execute the same curl command:
➜ curl -i "[http://err-test.192.168.64.5.nip.io/err?code=413](http://err-test.192.168.64.5.nip.io/err?code=413)"
HTTP/1.1 413 Request Entity Too Large
Server: nginx/1.15.10
Date: Sun, 05 May 2019 12:09:21 GMT
Content-Type: */*
Transfer-Encoding: chunked
Connection: close4xx html
You will have the custom error page with the correct HTTP status code.
Since you trap 503 status, scale down the replica.
Execute command:
$ kubectl scale deploy err-status-test --replicas=0
If you will access the application again, you will see the custom error page with the status code shown as 503 which is expected.
More information you can find here: custom-backend-errors.