
In diesem Artikel möchte ich über zwei Funktionen von NGINX Ingress berichten, die mit der Darstellung personalisierter Fehlerseiten verbunden sind, sowie über die bestehenden Einschränkungen und deren Umgehungsmöglichkeiten.
1. Ändern des standardmäßigen Backends
Standardmäßig verwendet NGINX Ingress das Default-Backend, das die entsprechende Funktion erfüllt. Das bedeutet, dass wir bei einer Anfrage an das Ingress mit einem Host, der nicht in den Ingress-Ressourcen vorhanden ist, eine solche Seite mit dem Antwortcode 404 erhalten:
![]()
Immer häufiger kommen jedoch unsere Kunden mit der Bitte, anstelle des standardmäßigen 404 ihre eigene Seite mit dem Firmenlogo und weiteren Annehmlichkeiten anzuzeigen. Dafür hat NGINX Ingress zu überschreiben default-backend-service. Der gleichnamigen Option übergeben wir als Argument den Eintrag im Format namespace/servicename. Der Port des Dienstes sollte 80 sein.
Dafür müssen Sie Ihr eigenes Pod (Deployment) und einen Dienst mit Ihrer Anwendung erstellen ( aus dem Repository ingress-nginx), welches 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ärz 2019 05:38:15 GMT
Inhaltstyp: */*
Transfer-Encoding: chunked
Verbindung: Keep-Alive
<span>Die von Ihnen gesuchte Seite konnte nicht gefunden werden.</span> Somit gelangen alle Domänen, die nicht explizit über YAML mit kind: Ingress, erstellt wurden, ins Default-Backend. In der obigen Auflistung wurde die solche Domäne sadsdasdas.
2. Verarbeitung von HTTP-Fehlern in der Anwendung über das Default-Backend
Eine andere Situation sind die mit HTTP-Fehlern endenden Anfragen (404, 500, 502…) an die Anwendung, in der solche Situationen nicht behandelt werden (es werden keine entsprechenden ansprechenden Seiten generiert). Dies kann auch durch das Bestreben der Entwickler verursacht werden, in vielen Anwendungen identische Fehlerseiten auszugeben.
Für die Umsetzung dieses Szenarios auf der Serverseite müssen wir:
- Die oben beschriebene Anweisung über das Default-Backend ausführen;
- Im Konfigurations-ConfigMap nginx-ingress den Schlüssel
custom-http-errors, zum Beispiel mit dem Wert404,503(entsprechend den Fehlermeldungscodes, auf die sich die neue Regel bezieht).
Das erwartete Ergebnis ist erreicht: Bei der Arbeit mit der Clientanwendung und dem Erhalt 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 statt 200 zurückgibt. NGINX ändert die Antwort des benutzerdefinierten Default-Backends nicht.Die Sache ist die, dass bei der Weiterleitung der Anfrage in den Headern nützliche Informationen mit dem vorherigen Antwortcode und zusätzlichen Informationen enthalten sein werden (die vollständige Liste ist verfügbar ).
Das bedeutet, dass Sie selbst sich um den korrekten Antwortcode kümmern müssen. aus der Dokumentation, wie das funktioniert.
Verschiedene Anwendungen - unterschiedliche Standard-Backends
Um zu vermeiden, dass die Lösung global für den gesamten Cluster gilt, sondern nur für bestimmte Anwendungen, müssen wir zuerst die Version von Ingress überprüfen. Wenn sie übereinstimmt mit 0.23 oder höher, verwenden Sie die "native" Annotations von Ingress:
- Wir können
default-backendfür jede von Ingress mit ; - Wir können
custom-http-errorsfür jede von Ingress mit .
Infolgedessen wird die Ingress-Ressource ungefähr 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 Service error-pages mit allen benötigten Headers umgeleitet.
Im in früheren Versionen von Ingress gab es diese Möglichkeit nicht (). Und wenn Sie in Ihrem Cluster 2 völlig verschiedene Anwendungen haben und für jede von ihnen unterschiedliche Default-Backend-Services und die Verarbeitung verschiedener Fehlercodes angeben möchten, müssen Sie Workarounds nutzen, von denen wir zwei haben.
Ingress < 0.23: erster Ansatz
Diese Option ist einfacher. Als Anwendung, die ihre Seiten ausgibt, haben wir ein einfaches HTML, das nicht in der Lage ist, auf Header zu schauen und korrekte Antwortcodes auszugeben. Solch eine Anwendung wird mit Ingress unter der URL bereitgestellt /error-pages, und im Verzeichnis ws liegt das ausgegebene HTML.
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 Dienst für dieses Deployment sollte vom Typ ClusterIP sein.
Dabei fügen wir in der Anwendung, in der wir den Fehler verarbeiten, im Ingress einen 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: zweite Variante
Variante für eine Anwendung, die in der Lage ist, Header zu verarbeiten... Und das ist überhaupt der korrektere Weg, entlehnt von custom-http-errors. Deren manuelle Verwendung (Kopieren) ermöglicht es, die globalen Einstellungen nicht zu ändern.
Die Schritte sind folgende. Wir erstellen mit einer Anwendung, die in der Lage ist, die benötigten Header zu hören und korrekt zu antworten. Wir fügen im Ingress der Anwendung das 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, müssen wir für jeden Fehler, den wir behandeln möchten, einen eigenen Ort (location) erstellen, wo alle notwendigen Header ersetzt werden, wie im „Ursprünglichen“ . So können wir verschiedene personalisierte Fehlerseiten sogar für einzelne Locations und Server erstellen.
P.S.
Noch etwas aus der Reihe K8s Tipps & Tricks:
- «»;
- «»;
- «»;
- «».
Lesen Sie auch in unserem Blog:
- «»;
- «».
Quelle: habr.com
