
En este artículo, quiero hablar sobre dos capacidades de NGINX Ingress relacionadas con la presentación de páginas personalizadas de errores, así como las limitaciones existentes y cómo superarlas.
1. Cambiar el backend por defecto
Por defecto, NGINX Ingress utiliza un backend por defecto que cumple con la función correspondiente. Esto significa que, al hacer una solicitud a Ingress con un host que no está en los recursos de Ingress, recibimos una página con el código de respuesta 404:
![]()
Sin embargo, cada vez más, nuestros clientes nos piden que en lugar del estándar 404 se muestre su página con el logotipo de la empresa y otras comodidades. Para esto, NGINX Ingress tiene de sobreescribir el servicio-default-backend.Pasamos el argumento del formato correspondiente a la opción del mismo nombre namespace/servicename.El puerto del servicio debe ser 80.
Para esto, es necesario crear su pod (deployment) y servicio con su aplicación ( del repositorio ingress-nginx), que se entregará en lugar del backend por defecto.
Aquí hay una pequeña ilustración:
~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 No Encontrado
Fecha: Lun, 11 Mar 2019 05:38:15 GMT
Tipo de Contenido: *
Transferencia: en fragmentos
Conexión: mantener viva
<span>La página que buscas no se pudo encontrar.</span> Así, todos los dominios que no se han creado explícitamente a través de YAML con kind: Ingresscaen en el backend por defecto. En el listado anterior, ese dominio fue sadsdasdas.
2. Manejo de errores HTTP en la aplicación a través del backend por defecto
Otra situación son las solicitudes a la aplicación que terminan con errores HTTP (404, 500, 502…) donde no se manejan tales situaciones (no se generan las páginas bonitas correspondientes). Esto también puede ser debido al deseo de los desarrolladores de ofrecer páginas de error iguales en múltiples aplicaciones.
Para implementar este caso en el lado del servidor, necesitamos:
- Ejecutar la instrucción anterior del punto sobre el backend por defecto;
- En el ConfigMap de configuración nginx-ingress, agregar la clave
custom-http-errors,por ejemplo, con el valor404,503(que debe corresponder a los códigos de error a los que se aplicará la nueva regla).
El resultado esperado se logra: al trabajar con la aplicación del cliente y recibir un error con el código de respuesta 404 o 503, la solicitud se redirigirá automáticamente al nuevo backend por defecto...
Sin embargo, al desarrollar la aplicación para el backend por defecto y custom-http-errors, es importante considerar una característica esencial:
!!! Importante: Se espera que el backend personalizado devuelva el código de estado HTTP correcto en lugar de 200. NGINX no cambia la respuesta del backend por defecto personalizado.Lo que ocurre es que al redirigir la solicitud, habrá información útil en los encabezados con el código de respuesta anterior y información adicional (su lista completa está disponible ).
Esto significa que usted mismo debe ocuparase del código de respuesta correcto. de la documentación sobre cómo funciona esto.
Diferentes aplicaciones requieren distintos backends predeterminados
Para 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 con 0.23 o superior, utilice las anotaciones "nativas" de Ingress:
- Podemos sobrescribir
el backend predeterminadopara cada de Ingress con ; - Podemos sobrescribir
custom-http-errors,para cada de Ingress con .
Como resultado, el recurso Ingress se verá aproximadamente 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: 80En este caso, los errores 404 y 502 se redirigirán al servicio error-pages con todos los encabezados necesarios.
En en versiones anteriores de Ingress esta posibilidad no existía (). Y si en su clúster está funcionando 2 aplicaciones completamente diferentes y desea especificar diferentes servicios backend predeterminados y manejar diferentes códigos de error para cada una — para eso deberá utilizar soluciones alternativas, de las cuales tenemos dos.
Ingress < 0.23: el primer enfoque
Esta opción es más simple. Como aplicación que entrega sus páginas, tenemos un HTML normal, que no puede verificar los encabezados y entregar códigos de respuesta correctos. Esta aplicación se implementa con Ingress con la URL /error-pages, y en el directorio ws se encontrará el HTML que se entrega.
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: 80El servicio para este despliegue debe ser del tipo ClusterIP.
Al mismo tiempo, en la aplicación donde vamos a manejar el error, en Ingress añadimos un server-snippet o configuration-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;
}Ingress < 0.23: segunda opción
Opción para una aplicación que puede procesar encabezados… Y en general, este es un camino más correcto, tomado de custom-http-errors. Su uso manual (copiado) permitirá no cambiar la configuración global.
Los pasos son los siguientes. Creamos con la aplicación que puede escuchar los encabezados necesarios y responder correctamente. Agregamos a Ingress de la aplicación server-snippet 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 se puede ver, para cada error que queremos manejar, necesitamos crear nuestra ubicación, donde se proporcionarán todos los encabezados necesarios, como en el 'original' . Así podemos crear diferentes páginas de error personalizadas incluso para ubicaciones y servidores específicos.
P.D.
Otra de la serie K8s tips & tricks:
- «»;
- «»;
- «»;
- «».
También puedes leer en nuestro blog:
- «»;
- «».
Fuente: habr.com
