
In diesem Artikel möchte ich zwei Funktionen von NGINX Ingress vorstellen, die mit der Anzeige von personalisierten Fehlerseiten verbunden sind, sowie die bestehenden Einschränkungen und mögliche Lösungen dafür.
1. Änderung des Standard-Backends
Standardmäßig verwendet NGINX Ingress ein Default-Backend, das diese Funktion erfüllt. Das bedeutet, dass bei einer Anfrage an den Ingress mit einem Host, der nicht in den Ingress-Ressourcen vorhanden ist, eine Seite mit dem Antwortcode 404 angezeigt wird:
![]()
Immer häufiger kommen jedoch unsere Kunden mit der Bitte, anstelle des standardmäßigen 404 eine eigene Seite mit ihrem Logo und weiteren Annehmlichkeiten anzuzeigen. Dafür bietet NGINX Ingress das default-backend-service. Als Argument für die gleichnamige Option übergeben wir den Eintrag im Format namespace/servicename. Der Port des Dienstes muss 80 sein.
Dazu ist es notwendig, einen eigenen Pod (Deployment) und einen Service mit Ihrer Anwendung zu erstellen ( aus dem Repository ingress-nginx), das anstelle des Default-Backends ausgegeben wird.
Hier ist eine kleine Illustration:
~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 Nicht gefunden
Datum: Mo, 11. Mär 2019 05:38:15 GMT
Content-Type: */*
Transfer-Encoding: chunked
Verbindung: keep-alive
<span>Die angeforderte Seite konnte nicht gefunden werden.</span> So gelangen alle Domains, die nicht ausdrücklich über YAML mit kind: Ingresserstellt wurden, ins Default-Backend. Im obigen Listing wurde somit diese Domain. sadsdasdas.
2. Verarbeitung von HTTP-Fehlern in der Anwendung durch das Default-Backend
Ein weiteres Szenario sind HTTP-Fehler (404, 500, 502...), die bei Anfragen an eine Anwendung auftreten, die solche Fälle nicht behandelt (es werden keine entsprechenden schönen Seiten generiert). Dies kann auch durch den Wunsch der Entwickler verursacht werden, identische Fehlerseiten in mehreren Anwendungen bereitzustellen.
Um diesen Anwendungsfall auf der Serverseite zu realisieren, benötigen wir:
- Führen Sie die oben genannte Anweisung zum Default-Backend aus;
- Fügen Sie dem ConfigMap nginx-ingress den Schlüssel
custom-http-errors, beispielsweise mit dem Wert404,503(offensichtlich entsprechend den Fehlercodes, auf die die neue Regel zutrifft).
Das erwartete Ergebnis wurde erreicht: Bei der Nutzung der Clientanwendung und dem Auftreten eines Fehlers mit dem Antwortcode 404 oder 503 wird die Anfrage automatisch an das neue Default-Backend umgeleitet...
Bei der Entwicklung der Anwendung für das Default-Backend und custom-http-errors muss jedoch eine wichtige Besonderheit berücksichtigt werden:
!!! Wichtig: Das benutzerdefinierte Backend wird erwartet, dass es den korrekten HTTP-Statuscode anstelle von 200 zurückgibt. NGINX ändert die Antwort des benutzerdefinierten Default-Backends nicht.Das Problem ist, dass bei der Weiterleitung einer Anfrage im Header nützliche Informationen mit dem vorherigen Antwortcode und zusätzlichen Informationen vorhanden sind (eine vollständige Liste finden Sie in der Dokumentation). ).
Das bedeutet, dass Sie selbst für den korrekten Antwortcode sorgen müssen.. aus der Dokumentation, wie das funktioniert.
Für verschiedene Anwendungen gibt es unterschiedliche Standard-Backends.
Damit die Lösung nicht global für das gesamte Cluster gilt, sondern nur für spezifische Anwendungen, sollten Sie zunächst die Version von Ingress überprüfen. Wenn sie 0.23 oder höher ist,verwenden Sie die "native" Annotationen von Ingress:
- Wir können den
default-backendfür jede von Ingress mit ; - Wir können den
custom-http-errorsfür jede von Ingress mit .
In der Folge wird die Ingress-Ressource etwa so aussehen:
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 diesem Fall werden die Fehler 404 und 502 an den Dienst error-pages mit allen erforderlichen Headers weitergeleitet.
In In früheren Versionen von Ingress gab es diese Möglichkeit nicht. (). Und wenn in Ihrem Cluster zwei völlig verschiedene Anwendungen laufen und Sie für jede von ihnen unterschiedliche default-backend-service und die Verarbeitung verschiedener Fehlercodes angeben möchten – müssen Sie dafür Workarounds nutzen, von denen wir zwei haben.
Ingress < 0.23: erster Ansatz
Diese Option ist einfacher. Für die Anwendung, die ihre Seiten bereitstellt, haben wir normales HTML, das nicht auf Header schauen und korrekte Antwortcodes zurückgeben kann. Eine solche Anwendung wird mit Ingress unter der URL /error-pages, und im Verzeichnis ws wird das ausgelieferte HTML liegen.
Illustration 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: 80Der Service für dieses Deployment sollte vom Typ ClusterIP sein.
In der Anwendung, in der wir den Fehler behandeln, fügen wir im Ingress server-snippet oder configuration-snippet mit folgendem Inhalt hinzu:
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: zweiter Ansatz
Eine Variante für Anwendungen, die Header verarbeiten können... Im Übrigen ist dies der korrekteste Weg, abgeleitet aus custom-http-errors. Die manuelle Verwendung (Kopieren) erlaubt es, globale Einstellungen nicht zu ändern.
Die Schritte sind folgende: Wir erstellen mit einer Anwendung, die in der Lage ist, die erforderlichen Header zu lauschen und korrekt zu antworten. Fügen Sie im Ingress der Anwendung den server-snippet mit folgendem Inhalt hinzu:
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;
}Wie zu sehen ist, muss für jeden Fehler, den wir behandeln möchten, eine eigene Location erstellt werden, in der alle notwendigen Header wie im „Original“ eingesetzt werden. . So können wir verschiedene personalisierte Fehlerseiten sogar für einzelne Standorte und Server erstellen.
P.S.
Weitere aus der Reihe K8s Tipps & Tricks:
- «»;
- «»;
- «»;
- «».
Lesen Sie auch in unserem Blog:
- «»;
- «».
Quelle: habr.com
