
In questo articolo voglio parlare di due possibilità di NGINX Ingress relative alla visualizzazione di pagine di errore personalizzate, nonché delle limitazioni esistenti e dei modi per superarle.
1. Modificare il backend predefinito
Per impostazione predefinita, in NGINX Ingress viene utilizzato il backend predefinito, che svolge la funzione corrispondente. Ciò significa che quando si richiede un Ingress specificando un host non presente nelle risorse Ingress, otteniamo una pagina con codice di risposta 404:
![]()
Tuttavia, sempre più spesso i nostri clienti chiedono di mostrare la propria pagina con logo aziendale e altre comodità anziché il consueto 404. A tal fine, NGINX Ingress offre per sovrascrivere default-backend-service. Per l'opzione omonima, passiamo come argomento una registrazione nel formato namespace/servicename. La porta del servizio deve essere 80.
Per fare ciò, è necessario creare il proprio pod (deployment) e servizio con la propria applicazione ( del repository ingress-nginx), che verrà restituita invece del backend predefinito.
Ecco una piccola illustrazione:
~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 Not Found
Date: Lun, 11 Mar 2019 05:38:15 GMT
Content-Type: */*
Transfer-Encoding: chunked
Connection: keep-alive
<span>La pagina che stai cercando non è stata trovata.</span> Pertanto, tutti i domini che non sono stati esplicitamente creati tramite YAML con kind: Ingress, vanno a finire nel default-backend. Nell'elenco sopra, tale dominio è diventato sadsdasdas.
2. Gestione degli errori HTTP nell'applicazione tramite il backend predefinito
Un'altra situazione riguarda le richieste all'applicazione che terminano con errori HTTP (404, 500, 502…) e in cui queste situazioni non vengono gestite (non vengono generate pagine belle corrispondenti). Questo può anche essere causato dalla volontà degli sviluppatori di restituire pagine di errore identiche in molte applicazioni.
Per implementare questo caso sul lato server, è necessario:
- Eseguire le istruzioni sopra riportate riguardanti il backend predefinito;
- Aggiungere la chiave
custom-http-errorsal ConfigMap nginx-ingress, ad esempio, con valore404,503(ovviamente, corrisponde ai codici di errore a cui si applica la nuova regola).
Il risultato atteso è stato raggiunto: quando l'applicazione client lavora e riceve un errore con codice di risposta 404 o 503, la richiesta verrà automaticamente reindirizzata al nuovo backend predefinito…
Tuttavia, nella sviluppo dell'applicazione per il backend predefinito e custom-http-errors è importante considerare una caratteristica fondamentale:
!!! Importante Il backend personalizzato deve restituire il corretto codice di stato HTTP invece di 200. NGINX non modifica la risposta dal backend predefinito personalizzato.Il fatto è che, durante il reindirizzamento della richiesta, ci sarà un'informazione utile negli header con il precedente codice di risposta e informazioni aggiuntive (l'elenco completo è disponibile ).
Questo significa che dovete occupa[vi] del codice di risposta corretto. dalla documentazione su come funziona.
Applicazioni diverse - backend predefiniti diversi
Affinché la soluzione non sia globale per l'intero cluster, ma si riferisca solo a specifiche applicazioni, bisogna prima controllare la versione di Ingress. Se corrisponde a 0.23 o superiore, utilizzare le annotazioni "native" di Ingress:
- Possiamo sovrascrivere
default-backendper ogni di Ingress con ; - Possiamo sovrascrivere
custom-http-errorsper ogni di Ingress con .
Di conseguenza, la risorsa Ingress avrà un aspetto simile a questo:
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: 80In questo caso, gli errori 404 e 502 verranno reindirizzati al servizio error-pages con tutti gli header necessari.
In nelle versioni precedenti di Ingress non c'era questa possibilità (). E se nel vostro cluster stanno funzionando 2 applicazioni completamente diverse e volete specificare per ciascuna di esse diversi default-backend-service e gestire diversi codici di errore - dovrete utilizzare workaround, di cui ne abbiamo due.
Ingress < 0.23: primo approccio
Questa opzione è più semplice. Come applicazione che fornisce le proprie pagine, abbiamo un comune HTML, che non è in grado di analizzare gli header e di fornire i codici di risposta corretti. Tale applicazione viene implementata con Ingress con URL /error-pages, mentre nella directory ws ci sarà l'HTML fornito.
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: 80Il servizio per questa distribuzione deve essere di tipo ClusterIP.
Nel contempo, nell'applicazione in cui gestiremo l'errore, in Ingress aggiungiamo server-snippet o configuration-snippet 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;
}Ingress < 0.23: il secondo approccio
Opzione per un'applicazione in grado di gestire gli header... È anche un percorso più corretto, preso in prestito da custom-http-errors. L'uso manuale (copia) non modificherà le impostazioni globali.
I passi sono i seguenti. Creiamo con un'app che può ascoltare gli header necessari e rispondere correttamente. Aggiungiamo nel server-snippet dell'Ingress dell'applicazione 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 si può vedere, per ogni errore che desideriamo gestire, è necessario creare un proprio location, dove verranno inseriti tutti gli header necessari, come in "native" . In questo modo possiamo creare diverse pagine personalizzate di errore anche per singoli location e server.
P.S.
Altro dal ciclo K8s tips & tricks:
- «»;
- «»;
- «»;
- «».
Leggi anche nel nostro blog:
- «»;
- «».
Fonte: habr.com
