Consejos y trucos de Kubernetes: páginas de error personalizadas en NGINX Ingress

Consejos y trucos de Kubernetes: páginas de error personalizadas en NGINX Ingress

En este artículo, quiero hablar sobre dos características de NGINX Ingress relacionadas con la visualización de páginas de error personalizadas, así como las limitaciones que existen en ellas y las formas de solucionarlas.

1. Cambiar el backend predeterminado

De forma predeterminada, NGINX Ingress utiliza el backend predeterminado, que realiza la función correspondiente. Esto significa que al solicitar un Ingress especificando un host que no está en los recursos de Ingress, recibimos la siguiente página con un código de respuesta 404:

Consejos y trucos de Kubernetes: páginas de error personalizadas en NGINX Ingress

Sin embargo, cada vez más a menudo nuestros clientes vienen con una solicitud para mostrar su página con un logotipo corporativo y otras comodidades en lugar del estándar 404. Para hacer esto, NGINX Ingress tiene capacidad incorporada redefinir default-backend-service. Pasamos la entrada de formato como argumento a la opción del mismo nombre. namespace/servicename. El puerto del servicio debe ser 80.

Para hacer esto, necesita crear su propio pod (implementación) y servicio con su aplicación (implementación de ejemplo en YAML del repositorio ingress-nginx), que se proporcionará en lugar del backend predeterminado.

He aquí una pequeña ilustración:

~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 Not Found
Date: Mon, 11 Mar 2019 05:38:15 GMT
Content-Type: */*
Transfer-Encoding: chunked
Connection: keep-alive

<span>The page you're looking for could not be found.</span>

Entonces, todos los dominios que no se crean explícitamente a través de YAML con kind: Ingress, cae en el backend predeterminado. En el listado anterior, este dominio se convirtió sadsdasdas.

2. Manejo de errores HTTP en la aplicación utilizando el backend predeterminado

Otra situación son las solicitudes que terminan en errores HTTP (404, 500, 502...) a una aplicación que no procesa tales situaciones (no se generan las páginas hermosas correspondientes). Esto también puede deberse al deseo de los desarrolladores de mostrar las mismas páginas de error en varias aplicaciones.

Para implementar este caso en el lado del servidor necesitamos:

  1. Siga las instrucciones anteriores del párrafo sobre el backend predeterminado;
  2. Agregue una clave al ConfigMap de configuración de nginx-ingress custom-http-errors, por ejemplo, con el valor 404,503 (obviamente corresponde a los códigos de error que cubre la nueva regla).

Se ha logrado el resultado esperado: cuando la aplicación cliente se está ejecutando y recibe un error con el código de respuesta 404 o 503, la solicitud será redirigida automáticamente al nuevo backend predeterminado...

Sin embargo, al desarrollar una aplicación para backend predeterminado y errores http personalizados, es necesario tener en cuenta una característica importante:

!!! Important 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.

El hecho es que cuando se redirige una solicitud, los encabezados contendrán información útil con el código de respuesta anterior e información adicional (su lista completa está disponible aquí).

Esto significa que usted mismo debe cuida el código de respuesta correcto. He aquí un ejemplo de la documentación cómo funciona.

Diferentes aplicaciones tienen diferentes backends predeterminados

Para asegurarse de que la solución no sea global para todo el clúster, sino que se aplique solo a aplicaciones específicas, primero debe verificar la versión de Ingress. si coincide 0.23 o más, utilice las anotaciones nativas de Ingress:

  1. Podemos anular default-backend para cada de ingreso usando anotaciones;
  2. Podemos anular custom-http-errors para cada de ingreso usando anotaciones.

Como resultado, el recurso de Ingress se verá así:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}-app2
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/custom-http-errors: "404,502"
    nginx.ingress.kubernetes.io/default-backend: error-pages
spec:
  tls:
  - hosts:
    - app2.example.com
    secretName: wildcard-tls
  rules:
  - host: app2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Chart.Name }}-app2
          servicePort: 80

En este caso, los errores 404 y 502 serán redirigidos al servicio de páginas de error con todos los encabezados necesarios.

В Las versiones anteriores de Ingress no tenían esta característica. (compromiso fatídico en 0.23). Y si tiene 2 aplicaciones completamente diferentes ejecutándose en su clúster y desea especificar un servicio backend predeterminado diferente y procesar diferentes códigos de error para cada una de ellas, para ello tendrá que utilizar soluciones alternativas, de las cuales tenemos dos.

Ingreso <0.23: acercarse a uno

Esta opción es más sencilla. Como aplicación que sirve sus páginas, tenemos HTML normal, que no sabe cómo mirar los encabezados y devolver los códigos de respuesta correctos. Una aplicación de este tipo se implementa con Ingress desde la URL /error-pages, y en el catálogo ws será el HTML devuelto.

Ilustración en YAML:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}-app2
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/server-snippet: |
      proxy_intercept_errors on;
      error_page 500 501 502 503 504 @error_pages;
      location @error_pages {
        rewrite ^ /error-pages/other/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }
spec:
  tls:
  - hosts:
    - app2.example.com
    secretName: wildcard-tls
  rules:
  - host: app2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Chart.Name }}-app2
          servicePort: 80

El servicio para esta implementación debe ser del tipo ClusterIP.

Al mismo tiempo, en la aplicación donde procesaremos el error, en Ingress agregamos un server-snippet o configuración-snippet con el siguiente contenido:

nginx.ingress.kubernetes.io    /server-snippet: |
      proxy_intercept_errors on;
      error_page 500 501 502 503 504 @error_pages;
      location @error_pages {
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }

Ingreso < 0.23: segundo enfoque

Una opción para una aplicación que puede procesar encabezados... Y, en general, esta es una forma más correcta, tomada de errores http personalizados. Usarlo manualmente (copiar) le permitirá no cambiar la configuración global.

Los pasos son los siguientes. Nosotros creamos mismo despliegue con una aplicación que pueda escuchar los titulares necesarios y responder correctamente. Agregue un fragmento de servidor a la aplicación Ingress con el siguiente contenido:

nginx.ingress.kubernetes.io    /server-snippet: |
      proxy_intercept_errors off;
      error_page 404 = @custom_404;
      error_page 503 = @custom_503;
      location @custom_404 {
        internal;
        proxy_intercept_errors off;
        proxy_set_header       X-Code             404;
        proxy_set_header       X-Format           $http_accept;
        proxy_set_header       X-Original-URI     $request_uri;
        proxy_set_header       X-Namespace        $namespace;
        proxy_set_header       X-Ingress-Name     $ingress_name;
        proxy_set_header       X-Service-Name     $service_name;
        proxy_set_header       X-Service-Port     $service_port;
        proxy_set_header       Host               $best_http_host;
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }
      location @custom_503 {
        internal;
        proxy_intercept_errors off;
        proxy_set_header       X-Code             503;
        proxy_set_header       X-Format           $http_accept;
        proxy_set_header       X-Original-URI     $request_uri;
        proxy_set_header       X-Namespace        $namespace;
        proxy_set_header       X-Ingress-Name     $ingress_name;
        proxy_set_header       X-Service-Name     $service_name;
        proxy_set_header       X-Service-Port     $service_port;
        proxy_set_header       Host               $best_http_host;
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }

Como puedes ver, para cada error que queramos procesar, necesitamos crear nuestra propia ubicación, donde se insertarán todos los encabezados necesarios, como en el “nativo”. páginas-de-error-personalizadas. De esta manera podemos crear diferentes páginas de error personalizadas incluso para ubicaciones y servidores individuales.

PS

Otros de la serie de consejos y trucos del K8:

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario