
In diesem Artikel möchte ich über zwei NGINX Ingress-Funktionen sprechen, die sich auf die Anzeige personalisierter Fehlerseiten beziehen, sowie auf die darin enthaltenen Einschränkungen und Möglichkeiten, diese zu umgehen.
1. Ändern des Standard-Backends
Standardmäßig verwendet NGINX Ingress das Standard-Backend, das die entsprechende Funktion ausführt. Dies bedeutet, dass beim Abfragen von Ingress mit einem Host, der sich nicht in den Ingress-Ressourcen befindet, eine Seite mit einem 404-Antwortcode angezeigt wird:

Unsere Kunden erhalten jedoch immer häufiger die Aufforderung, anstelle des Standards 404 ihre Seite mit einem Firmenlogo und anderen Annehmlichkeiten anzuzeigen. Zu diesem Zweck verfügt NGINX Ingress über eine
integrierte Funktion zum Überschreiben des
default-backend-service
. Der gleichnamigen Option als Argument wird
namespace/servicename
Format übergeben. Der Service-Port muss 80 sein.
Erstellen Sie dazu mit Ihrer Anwendung
einen eigenen Pod (Bereitstellung) und Service (
eine Beispielimplementierung in YAML aus dem Ingress-Nginx-Repository), der anstelle des Standard-Backends angegeben wird.
Hier ist eine kleine Illustration:
~$ 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>
Somit fallen alle Domänen, die nicht explizit über YAML mit
kind: Ingress
in das Standard-Backend. In der obigen Auflistung ist
sadsdasdas
zu dieser Domäne geworden.
2. Verarbeiten von HTTP-Fehlern in der Anwendung mithilfe des Standard-Backends
Eine andere Situation sind Anforderungen an eine Anwendung, in denen HTTP-Situationen (404, 500, 502 ...), in denen solche Situationen nicht verarbeitet werden (entsprechende schöne Seiten werden nicht generiert), HTTP-Fehler verursachen. Dies kann auch durch den Wunsch der Entwickler verursacht werden, in vielen Anwendungen dieselben Fehlerseiten anzugeben.
Um diesen Fall auf der Serverseite zu implementieren, benötigen wir:
- Befolgen Sie die obigen Anweisungen aus dem Artikel zum Standard-Backend.
- Fügen Sie der Konfiguration ConfigMap nginx-ingress den
custom-http-errors
Fehlerschlüssel hinzu, z. B. mit einem Wert von 404,503
(offensichtlich entspricht er den Fehlercodes, die von der neuen Regel abgedeckt werden).
Das erwartete Ergebnis wird erzielt: Wenn die Clientanwendung ausgeführt wird und einen Fehler mit einem Antwortcode von 404 oder 503 empfängt, wird die Anforderung automatisch an das neue Standard-Backend umgeleitet ...
Bei der Entwicklung einer Anwendung für Standard-Backend- und benutzerdefinierte http-Fehler müssen Sie jedoch eine wichtige Funktion berücksichtigen:
!!! 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.
Tatsache ist, dass die Kopfzeilen beim Umleiten einer Anforderung nützliche Informationen mit dem vorherigen Antwortcode und zusätzlichen Informationen enthalten (eine vollständige Liste davon finden Sie
hier ).
Dies bedeutet, dass Sie sich selbst
um den richtigen Antwortcode kümmern müssen.
Hier ist ein Beispiel aus der Dokumentation, wie dies funktioniert.
Für verschiedene Anwendungen - verschiedene Standard-Backends
Damit die Lösung nicht für den gesamten Cluster global ist, sondern nur für bestimmte Anwendungen gilt, müssen Sie zunächst die Version von Ingress überprüfen. Wenn es mit
0,23 oder höher übereinstimmt, verwenden Sie die nativen Ingress-Anmerkungen:
- Mithilfe der Annotation können wir das
default-backend
für jeden Ingress neu definieren. - Wir können
custom-http-errors
für jeden Ingress mithilfe von Anmerkungen überschreiben.
Infolgedessen sieht die Ingress-Ressource ungefähr so aus:
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 diesem Fall werden die Fehler 404 und 502 mit allen erforderlichen Headern an den Fehlerseitendienst umgeleitet.
In
früheren Versionen von Ingress war dies nicht möglich (das
schicksalhafte Festschreiben bei 0,23 ). Und wenn in Ihrem Cluster zwei völlig unterschiedliche Anwendungen ausgeführt werden und Sie einen unterschiedlichen Standard-Backend-Service angeben und für jeden unterschiedliche Fehlercodes behandeln möchten, müssen Sie hierfür Problemumgehungen verwenden, von denen wir zwei haben.
Ingress <0,23: Annäherung an eins
Diese Option ist einfacher. Als Anwendung, die ihre Seiten bereitstellt, haben wir reguläres HTML, das nicht weiß, wie man die Header betrachtet und die richtigen Antwortcodes angibt. Eine solche Anwendung wird mit Ingress mit URL-
/error-pages
, und der HTML-
ws
Verzeichnis
ws
.
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: 80
Der Dienst für diese Bereitstellung muss vom Typ ClusterIP sein.
Gleichzeitig fügen wir in der Anwendung, in der wir den Fehler behandeln, in Ingress Server-Snippet oder Konfigurations-Snippet mit den folgenden Inhalten 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: Annäherung an zwei
Eine Option für eine Anwendung, die Header verarbeiten kann ... Auf jeden Fall ist dies ein korrekterer Pfad, der aus benutzerdefinierten http-Fehlern entlehnt wurde. Wenn Sie es manuell verwenden (kopieren), können Sie die globalen Einstellungen nicht ändern.
Die Schritte sind wie folgt. Wir erstellen
dieselbe Bereitstellung mit einer Anwendung, die die erforderlichen Header abhören und korrekt reagieren kann. Fügen Sie Ingress Server-Snippet-Anwendungen mit den folgenden Inhalten 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 Sie sehen, müssen Sie für jeden Fehler, den wir behandeln möchten, Ihren Speicherort angeben, an dem alle erforderlichen Header ersetzt werden, wie auf den "nativen"
benutzerdefinierten Fehlerseiten . So können wir auch für einzelne Standorte und Server verschiedene personalisierte Seiten mit Fehlern erstellen.
PS
Andere aus dem K8s Tipps & Tricks-Zyklus:
Lesen Sie auch in unserem Blog: