Suggerimenti e trucchi Kubernetes: pagine di errore personalizzate in NGINX Ingress

Suggerimenti e trucchi Kubernetes: pagine di errore personalizzate in NGINX Ingress

In questo articolo, voglio parlare di due funzionalità di NGINX Ingress relative alla visualizzazione di pagine di errore personalizzate, nonché delle limitazioni che esistono in esse e dei modi per aggirarle.

1. Modifica del backend predefinito

Per impostazione predefinita, NGINX Ingress utilizza il backend predefinito, che esegue la funzione corrispondente. Ciò significa che quando richiediamo un Ingress specificando un host che non è nelle risorse Ingress, riceviamo la seguente pagina con un codice di risposta 404:

Suggerimenti e trucchi Kubernetes: pagine di errore personalizzate in NGINX Ingress

Tuttavia, sempre più spesso i nostri clienti chiedono di mostrare la loro pagina con un logo aziendale e altri servizi invece dello standard 404. Per fare ciò, NGINX Ingress ha capacità incorporata ridefinire default-backend-service. Passiamo la voce del formato come argomento all'opzione con lo stesso nome namespace/servicename. La porta del servizio dovrebbe essere 80.

Per fare ciò, devi creare il tuo pod (deployment) e il tuo servizio con la tua applicazione (esempio di implementazione in YAML dal repository ingress-nginx), che verrà fornito al posto del backend predefinito.

Ecco una piccola illustrazione:

~$ 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>

Quindi tutti i domini che non sono creati esplicitamente tramite YAML con kind: Ingress, cadono nel backend predefinito. Nell'elenco sopra, questo dominio è diventato sadsdasdas.

2. Gestione degli errori HTTP nell'applicazione utilizzando il backend predefinito

Un'altra situazione sono le richieste che terminano con errori HTTP (404, 500, 502...) a un'applicazione che non elabora tali situazioni (le belle pagine corrispondenti non vengono generate). Ciò potrebbe anche essere dovuto al desiderio degli sviluppatori di fornire le stesse pagine di errore in più applicazioni.

Per implementare questo caso lato server abbiamo bisogno di:

  1. Seguire le istruzioni sopra dal paragrafo sul backend predefinito;
  2. Aggiungi una chiave alla configurazione nginx-ingress ConfigMap custom-http-errors, ad esempio, con il valore 404,503 (ovviamente corrisponde ai codici errore che rientrano nella nuova regola).

Il risultato atteso è stato raggiunto: quando l'applicazione client è in esecuzione e riceve un errore con codice di risposta 404 o 503, la richiesta verrà automaticamente reindirizzata al nuovo backend predefinito...

Tuttavia, quando si sviluppa un'applicazione per il backend predefinito e gli errori http personalizzati, è necessario tenere in considerazione una caratteristica 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.

Il fatto è che quando una richiesta viene reindirizzata, le intestazioni conterranno informazioni utili con il codice di risposta precedente e informazioni aggiuntive (il loro elenco completo è disponibile qui).

Ciò significa che tu stesso devi fare attenzione al codice di risposta corretto. Ecco un esempio. dalla documentazione come funziona.

Applicazioni diverse hanno backend predefiniti diversi

Per garantire che la soluzione non sia globale per l'intero cluster, ma si applichi solo ad applicazioni specifiche, devi prima verificare la versione di Ingress. Se corrisponde 0.23 o superiore, utilizza le annotazioni Ingress native:

  1. Possiamo sovrascrivere default-backend per ogni Quello di Ingresso utilizzando le annotazioni;
  2. Possiamo sovrascrivere custom-http-errors per ogni Quello di Ingresso utilizzando le annotazioni.

Di conseguenza, la risorsa Ingress sarà simile a questa:

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

In questo caso, gli errori 404 e 502 verranno reindirizzati al servizio error-pages con tutte le intestazioni necessarie.

В le versioni precedenti di Ingress non disponevano di questa funzionalità (impegno fatidico a 0.23). E se hai 2 applicazioni completamente diverse in esecuzione nel tuo cluster e desideri specificare un diverso servizio di backend predefinito e l'elaborazione di codici di errore diversi per ciascuna di esse, per questo dovrai utilizzare soluzioni alternative, di cui ne abbiamo due.

Ingresso < 0.23: avvicinamento uno

Questa opzione è più semplice. Come applicazione che serve le sue pagine, abbiamo un normale HTML, che non sa come guardare le intestazioni e restituire i codici di risposta corretti. Tale applicazione viene distribuita con Ingress dall'URL /error-pagese nel catalogo ws sarà l'HTML restituito.

Illustrazione in 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

Il servizio per questa distribuzione deve essere di tipo ClusterIP.

Allo stesso tempo, nell'applicazione in cui elaboreremo l'errore, in Ingress aggiungiamo uno snippet di server o uno snippet di configurazione con il seguente contenuto:

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

Ingresso < 0.23: secondo approccio

Un'opzione per un'applicazione in grado di elaborare le intestazioni... E in generale questo è un modo più corretto, preso in prestito dagli errori http personalizzati. Usarlo manualmente (copiando) ti consentirà di non modificare le impostazioni globali.

I passi sono come segue. Noi creiamo stesso schieramento con un'applicazione in grado di ascoltare i titoli necessari e rispondere correttamente. Aggiungi uno snippet del server all'applicazione Ingress con il seguente contenuto:

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

Come puoi vedere, per ogni errore che vogliamo elaborare, dobbiamo creare una nostra posizione, dove verranno inserite tutte le intestazioni necessarie, come in quella “nativa”. pagine-di-errore-personalizzate. In questo modo possiamo creare diverse pagine di errore personalizzate anche per singole posizioni e server.

PS

Altro dalla serie di suggerimenti e trucchi K8:

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento