From 2e5e341ef05725e458eb0888facae29349081043 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Tue, 3 May 2016 23:58:54 -0300 Subject: [PATCH] Add example of custom error pages in nginx ingress controller --- controllers/nginx/README.md | 2 +- .../nginx/examples/custom-errors/README.md | 80 +++++++++++++++++++ .../custom-errors/custom-default-backend.yaml | 31 +++++++ .../custom-errors/rc-custom-errors.yaml | 46 +++++++++++ 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 controllers/nginx/examples/custom-errors/README.md create mode 100644 controllers/nginx/examples/custom-errors/custom-default-backend.yaml create mode 100644 controllers/nginx/examples/custom-errors/rc-custom-errors.yaml diff --git a/controllers/nginx/README.md b/controllers/nginx/README.md index c82d71c81..a038b83ce 100644 --- a/controllers/nginx/README.md +++ b/controllers/nginx/README.md @@ -208,7 +208,7 @@ In case of an error in a request the body of the response is obtained from the ` - `X-Code` indicates the HTTP code - `X-Format` the value of the `Accept` header -Using this two headers is possible to use a custom backend service like [this one](https://github.com/aledbf/contrib/tree/nginx-debug-server/Ingress/images/nginx-error-server) that inspect each request and returns a custom error page with the format expected by the client. This images handles `html` and `json` responses. +Using this two headers is possible to use a custom backend service like [this one](https://github.com/aledbf/contrib/tree/nginx-debug-server/Ingress/images/nginx-error-server) that inspect each request and returns a custom error page with the format expected by the client. Please check the example [custom-errors](examples/custom-errors/README.md) ## Troubleshooting diff --git a/controllers/nginx/examples/custom-errors/README.md b/controllers/nginx/examples/custom-errors/README.md new file mode 100644 index 000000000..e9faf1fc8 --- /dev/null +++ b/controllers/nginx/examples/custom-errors/README.md @@ -0,0 +1,80 @@ + +This example shows how is possible to use a custom backend to render custom error pages. The code of this example is located here [nginx-debug-server](https://github.com/aledbf/contrib/tree/nginx-debug-server) + + +The idea is to use the headers `X-Code` and `X-Format` that NGINX pass to the backend in case of an error to find out the best existent representation of the response to be returned. i.e. if the request contains an `Accept` header of type `json` the error should be in that format and not in `html` (the default in NGINX). + +First create the custom backend to use in the Ingress controller + +```$ kubectl create -f custom-default-backend.yaml +service "nginx-errors" created +replicationcontroller "nginx-errors" created +``` + +```$ kubectl get svc +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +echoheaders 10.3.0.7 nodes 80/TCP 23d +kubernetes 10.3.0.1 443/TCP 34d +nginx-errors 10.3.0.102 80/TCP 11s +``` + +```$ kubectl get rc +CONTROLLER REPLICAS AGE +echoheaders 1 19d +nginx-errors 1 19s +``` + +Next create the Ingress controller executing +``` +$ kubectl create -f rc-custom-errors.yaml +``` + +Now to check if this is working we use curl: + +``` +$ curl -v http://172.17.4.99/ +* Trying 172.17.4.99... +* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0) +> GET / HTTP/1.1 +> Host: 172.17.4.99 +> User-Agent: curl/7.43.0 +> Accept: */* +> +< HTTP/1.1 404 Not Found +< Server: nginx/1.10.0 +< Date: Wed, 04 May 2016 02:53:45 GMT +< Content-Type: text/html +< Transfer-Encoding: chunked +< Connection: keep-alive +< Vary: Accept-Encoding +< +The page you're looking for could not be found. + +* Connection #0 to host 172.17.4.99 left intact +``` + +Specifying json as expected format: + +``` +$ curl -v http://172.17.4.99/ -H 'Accept: application/json' +* Trying 172.17.4.99... +* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0) +> GET / HTTP/1.1 +> Host: 172.17.4.99 +> User-Agent: curl/7.43.0 +> Accept: application/json +> +< HTTP/1.1 404 Not Found +< Server: nginx/1.10.0 +< Date: Wed, 04 May 2016 02:54:00 GMT +< Content-Type: text/html +< Transfer-Encoding: chunked +< Connection: keep-alive +< Vary: Accept-Encoding +< +{ "message": "The page you're looking for could not be found" } + +* Connection #0 to host 172.17.4.99 left intact +``` + +By default the Ingress controller provides support for `html`, `json` and `XML`. diff --git a/controllers/nginx/examples/custom-errors/custom-default-backend.yaml b/controllers/nginx/examples/custom-errors/custom-default-backend.yaml new file mode 100644 index 000000000..fce7c0bcb --- /dev/null +++ b/controllers/nginx/examples/custom-errors/custom-default-backend.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx-errors + labels: + app: nginx-errors +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: nginx-errors +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: nginx-errors +spec: + replicas: 1 + template: + metadata: + labels: + app: nginx-errors + spec: + containers: + - name: nginx-errors + image: aledbf/nginx-error-server:0.1 + ports: + - containerPort: 80 \ No newline at end of file diff --git a/controllers/nginx/examples/custom-errors/rc-custom-errors.yaml b/controllers/nginx/examples/custom-errors/rc-custom-errors.yaml new file mode 100644 index 000000000..7a4a13a80 --- /dev/null +++ b/controllers/nginx/examples/custom-errors/rc-custom-errors.yaml @@ -0,0 +1,46 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: nginx-ingress-controller + labels: + k8s-app: nginx-ingress-lb +spec: + replicas: 1 + selector: + k8s-app: nginx-ingress-lb + template: + metadata: + labels: + k8s-app: nginx-ingress-lb + name: nginx-ingress-lb + spec: + terminationGracePeriodSeconds: 60 + containers: + - image: gcr.io/google_containers/nginx-ingress-controller:0.6 + name: nginx-ingress-lb + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 10249 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + # use downward API + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 80 + hostPort: 80 + - containerPort: 443 + hostPort: 443 + args: + - /nginx-ingress-controller + - --default-backend-service=default/nginx-errors