Consellos e trucos de Kubernetes: páxinas de erro personalizadas en NGINX Ingress

Consellos e trucos de Kubernetes: páxinas de erro personalizadas en NGINX Ingress

Neste artigo, quero falar de dúas funcións de NGINX Ingress relacionadas coa visualización de páxinas de erro personalizadas, así como das limitacións que existen nelas e das formas de evitarlas.

1. Cambiando o backend predeterminado

Por defecto, NGINX Ingress usa o backend predeterminado, que realiza a función correspondente. Isto significa que ao solicitar un Ingress especificando un host que non está nos recursos de Ingress, recibimos a seguinte páxina cun código de resposta 404:

Consellos e trucos de Kubernetes: páxinas de erro personalizadas en NGINX Ingress

Non obstante, cada vez máis a miúdo os nosos clientes solicitan mostrar a súa páxina cun logotipo corporativo e outras comodidades en lugar do estándar 404. Para iso, NGINX Ingress ten capacidade incorporada redefinir default-backend-service. Pasamos a entrada de formato como argumento á opción do mesmo nome namespace/servicename. O porto do servizo debería ser 80.

Para iso, cómpre crear o seu propio pod (implementación) e servizo coa súa aplicación (exemplo de implementación en YAML desde o repositorio ingress-nginx), que se dará en lugar do backend predeterminado.

Aquí tes unha pequena 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>

Polo tanto, todos os dominios que non se crean explícitamente mediante YAML con kind: Ingress, cae no backend predeterminado. Na lista anterior, este dominio converteuse en sadsdasdas.

2. Manexo de erros HTTP na aplicación usando o backend predeterminado

Outra situación son as solicitudes que rematan en erros HTTP (404, 500, 502...) a unha aplicación que non procesa tales situacións (non se xeran as páxinas bonitas correspondentes). Isto tamén pode deberse ao desexo dos desenvolvedores de servir as mesmas páxinas de erro en varias aplicacións.

Para implementar este caso no lado do servidor necesitamos:

  1. Siga as instrucións anteriores do parágrafo sobre o backend predeterminado;
  2. Engade unha clave á configuración de nginx-ingress ConfigMap custom-http-errors, por exemplo, co valor 404,503 (corresponde obviamente aos códigos de erro contemplados pola nova norma).

Conseguiuse o resultado esperado: cando a aplicación cliente está a executarse e recibe un erro co código de resposta 404 ou 503, a solicitude redirixirase automaticamente ao novo backend predeterminado...

Non obstante, ao desenvolver unha aplicación para o backend predeterminado e os erros de http personalizados, cómpre ter en conta unha 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.

O feito é que cando se redirecciona unha solicitude, as cabeceiras conterán información útil co código de resposta anterior e información adicional (a súa lista completa está dispoñible aquí).

Isto significa que vostede mesmo debe coida o código de resposta correcto. Aquí tes un exemplo a partir da documentación como funciona.

As diferentes aplicacións teñen diferentes backends predeterminados

Para garantir que a solución non é global para todo o clúster, senón que só se aplica a aplicacións específicas, primeiro cómpre comprobar a versión de Ingress. Se coincide 0.23 ou superior, use as anotacións de Ingress nativas:

  1. Podemos anular default-backend para de cada un Ingresos utilizando anotacións;
  2. Podemos anular custom-http-errors para de cada un Ingresos utilizando anotacións.

Como resultado, o recurso Ingress terá un aspecto similar ao seguinte:

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

Neste caso, os erros 404 e 502 serán redirixidos ao servizo de páxinas de erro con todas as cabeceiras necesarias.

В as versións anteriores de Ingress non tiñan esta función (cometido fatídico en 0.23). E se tes 2 aplicacións completamente diferentes en execución no teu clúster e queres especificar un servizo de backend predeterminado diferente e procesar códigos de erro diferentes para cada unha delas, para iso terás que utilizar solucións alternativas, das que temos dúas.

Entrada < 0.23: achégase a un

Esta opción é máis sinxela. Como aplicación que serve as súas páxinas, temos HTML normal, que non sabe mirar as cabeceiras e devolver os códigos de resposta correctos. Tal aplicación lánzase con Ingress desde o URL /error-pages, e no catálogo ws será o HTML devolto.

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

O servizo para esta implantación debe ser do tipo ClusterIP.

Ao mesmo tempo, na aplicación onde procesaremos o erro, en Ingress engadimos un fragmento de servidor ou fragmento de configuración co seguinte contido:

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;
      }

Entrada < 0.23: segunda aproximación

Unha opción para unha aplicación que pode procesar cabeceiras... E en xeral esta é unha forma máis correcta, tomada de custom-http-errors. Usalo manualmente (copiando) permitirache non cambiar a configuración global.

Os pasos son os seguintes. Nós creamos mesmo despregamento cunha aplicación que pode escoitar os titulares necesarios e responder correctamente. Engade un fragmento de servidor á aplicación Ingress co seguinte contido:

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 podes ver, para cada erro que queremos procesar, cómpre facer a nosa propia localización, onde se inserirán todas as cabeceiras necesarias, como na “nativa”. páxinas de erro personalizadas. Deste xeito, podemos crear diferentes páxinas de erro personalizadas incluso para localizacións e servidores individuais.

PS

Outros da serie de consellos e trucos K8s:

Lea tamén no noso blog:

Fonte: www.habr.com

Engadir un comentario