Sfaturi și trucuri Kubernetes: pagini de eroare personalizate în NGINX Ingress

Sfaturi și trucuri Kubernetes: pagini de eroare personalizate în NGINX Ingress

În acest articol, vreau să vorbesc despre două caracteristici ale NGINX Ingress legate de afișarea paginilor de eroare personalizate, precum și despre limitările care există în ele și despre modalitățile de a le evita.

1. Schimbarea backend-ului implicit

În mod implicit, NGINX Ingress utilizează backend-ul implicit, care îndeplinește funcția corespunzătoare. Aceasta înseamnă că atunci când solicităm un Ingress care specifică o gazdă care nu se află în resursele Ingress, primim următoarea pagină cu un cod de răspuns 404:

Sfaturi și trucuri Kubernetes: pagini de eroare personalizate în NGINX Ingress

Cu toate acestea, din ce în ce mai des clienții noștri vin cu o solicitare de a-și afișa pagina cu un logo corporativ și alte facilități în locul standardului 404. Pentru a face acest lucru, NGINX Ingress are capacitate încorporată redefiniți default-backend-service. Trecem intrarea de format ca argument la opțiunea cu același nume namespace/servicename. Portul serviciului ar trebui să fie 80.

Pentru a face acest lucru, trebuie să vă creați propriul pod (implementare) și service cu aplicația dvs. (exemplu de implementare în YAML din depozitul ingress-nginx), care va fi dat în locul backend-ului implicit.

Iată o mică ilustrare:

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

Deci, toate domeniile care nu sunt create în mod explicit prin YAML cu kind: Ingress, intră în default-backend. În lista de mai sus, acest domeniu a devenit sadsdasdas.

2. Gestionarea erorilor HTTP în aplicație folosind backend-ul implicit

O altă situație sunt solicitările care se termină cu erori HTTP (404, 500, 502...) către o aplicație care nu procesează astfel de situații (nu sunt generate paginile frumoase corespunzătoare). Acest lucru se poate datora și dorinței dezvoltatorilor de a difuza aceleași pagini de eroare în mai multe aplicații.

Pentru a implementa acest caz pe partea de server avem nevoie de:

  1. Urmați instrucțiunile de mai sus din paragraful despre backend implicit;
  2. Adăugați o cheie la configurația nginx-ingress ConfigMap custom-http-errors, de exemplu, cu valoarea 404,503 (corespunde evident codurilor de eroare care sunt acoperite de noua regulă).

Rezultatul așteptat a fost atins: atunci când aplicația client rulează și primește o eroare cu un cod de răspuns de 404 sau 503, cererea va fi redirecționată automat către noul backend implicit...

Cu toate acestea, atunci când dezvoltați o aplicație pentru backend implicit și erori de http personalizate, trebuie să luați în considerare o caracteristică importantă:

!!! 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.

Faptul este că atunci când o solicitare este redirecționată, anteturile vor conține informații utile cu codul de răspuns anterior și informații suplimentare (lista lor completă este disponibilă aici).

Asta înseamnă că tu însuți trebuie ai grijă de codul de răspuns corect. Iată un exemplu din documentație cum funcționează.

Aplicațiile diferite au backend-uri implicite diferite

Pentru a vă asigura că soluția nu este globală pentru întregul cluster, ci se aplică numai aplicațiilor specifice, trebuie mai întâi să verificați versiunea Ingress. Daca se potriveste 0.23 sau mai mare, utilizați adnotările native Ingress:

  1. Putem trece peste default-backend pentru fiecare Intrarea lui folosind adnotări;
  2. Putem trece peste custom-http-errors pentru fiecare Intrarea lui folosind adnotări.

Ca rezultat, resursa Ingress va arăta cam așa:

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

În acest caz, erorile 404 și 502 vor fi redirecționate către serviciul de pagini de eroare cu toate anteturile necesare.

В versiunile anterioare ale Ingress nu aveau această caracteristică (comite fatidic la 0.23). Și dacă aveți 2 aplicații complet diferite care rulează în clusterul dvs. și doriți să specificați un serviciu de backend implicit diferit și procesarea diferitelor coduri de eroare pentru fiecare dintre ele, pentru aceasta va trebui să utilizați soluții de soluționare, dintre care avem două.

Intrare < 0.23: apropierea unu

Această opțiune este mai simplă. Ca o aplicație care își servește paginile, avem HTML obișnuit, care nu știe să se uite la anteturi și să returneze codurile de răspuns corecte. O astfel de aplicație este lansată cu Ingress din url /error-pages, și în catalog ws va fi HTML-ul returnat.

Ilustrație în 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

Serviciul pentru această implementare trebuie să fie de tip ClusterIP.

Totodată, în aplicația în care vom procesa eroarea, în Ingress adăugăm un server-snippet sau configuration-snippet cu următorul conținut:

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

Intrare < 0.23: a doua abordare

O opțiune pentru o aplicație care poate procesa anteturi... Și, în general, aceasta este o modalitate mai corectă, împrumutată din custom-http-errors. Folosirea manuală (copiere) vă va permite să nu modificați setările globale.

Pașii sunt următorii. Noi creăm aceeași desfășurare cu o aplicație care poate asculta titlurile necesare și poate răspunde corect. Adăugați un fragment de server la aplicația Ingress cu următorul conținut:

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

După cum puteți vedea, pentru fiecare eroare pe care dorim să o procesăm, trebuie să ne facem propria locație, unde vor fi inserate toate anteturile necesare, ca în cel „nativ”. pagini-de-eroare-personalizate. În acest fel, putem crea diferite pagini de eroare personalizate chiar și pentru locații și servere individuale.

PS

Altele din seria de sfaturi și trucuri K8s:

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu