Porady i wskazówki Kubernetes: niestandardowe strony błędów w NGINX Ingress

Porady i wskazówki Kubernetes: niestandardowe strony błędów w NGINX Ingress

W tym artykule chcę omówić dwie funkcje NGINX Ingress związane z wyświetlaniem spersonalizowanych stron błędów, a także istniejące w nich ograniczenia i sposoby obejścia ich.

1. Zmiana domyślnego backendu

Domyślnie NGINX Ingress korzysta z domyślnego backendu, który wykonuje odpowiednią funkcję. Oznacza to, że w przypadku żądania Ingressu ze wskazaniem hosta, którego nie ma w zasobach Ingress, otrzymamy następującą stronę z kodem odpowiedzi 404:

Porady i wskazówki Kubernetes: niestandardowe strony błędów w NGINX Ingress

Jednak coraz częściej nasi klienci zwracają się z prośbą o wyświetlenie swojej strony z logo firmy i innymi udogodnieniami zamiast standardowego 404. Aby to zrobić, NGINX Ingress ma wbudowana funkcja przedefiniować default-backend-service. Wpis formatu przekazujemy jako argument opcji o tej samej nazwie namespace/servicename. Port usługi powinien mieć numer 80.

Aby to zrobić, musisz utworzyć własny pod (wdrożenie) i usługę ze swoją aplikacją (przykładowa implementacja w YAML z repozytorium ingress-nginx), który zostanie podany zamiast domyślnego backendu.

Oto mała ilustracja:

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

Zatem wszystkie domeny, które nie są jawnie utworzone za pomocą YAML z kind: Ingress, wpadnij do domyślnego backendu. Na powyższym wykazie ta domena stała się sadsdasdas.

2. Obsługa błędów HTTP w aplikacji przy wykorzystaniu domyślnego backendu

Inną sytuacją są żądania zakończone błędami HTTP (404, 500, 502...) kierowane do aplikacji, która nie przetwarza takich sytuacji (nie są generowane odpowiednie piękne strony). Może to również wynikać z chęci programistów do obsługi tych samych stron błędów w wielu aplikacjach.

Aby zaimplementować ten przypadek po stronie serwera, potrzebujemy:

  1. Postępuj zgodnie z instrukcjami powyżej z akapitu dotyczącego domyślnego backendu;
  2. Dodaj klucz do konfiguracji nginx-ingres ConfigMap custom-http-errorsna przykład z wartością 404,503 (oczywiście odpowiada kodom błędów objętych nową zasadą).

Oczekiwany rezultat został osiągnięty: gdy aplikacja kliencka jest uruchomiona i otrzyma błąd z kodem odpowiedzi 404 lub 503, żądanie zostanie automatycznie przekierowane do nowego domyślnego backendu...

Jednak tworząc aplikację dla domyślnego backendu i niestandardowych błędów http, należy wziąć pod uwagę ważną cechę:

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

Faktem jest, że w przypadku przekierowania żądania w nagłówkach będą znajdować się przydatne informacje z poprzednim kodem odpowiedzi oraz informacje dodatkowe (ich pełna lista jest dostępna tutaj).

Oznacza to, że sam musisz zadbaj o poprawny kod odpowiedzi. Oto przykład. z dokumentacji jak to działa.

Różne aplikacje mają różne domyślne backendy

Aby mieć pewność, że rozwiązanie nie jest globalne dla całego klastra, a dotyczy tylko konkretnych aplikacji, należy najpierw sprawdzić wersję Ingress. Jeśli pasuje 0.23 lub więcejużyj natywnych adnotacji Ingress:

  1. Możemy zastąpić default-backend dla każdy Ingressa za pomocą adnotacji;
  2. Możemy zastąpić custom-http-errors dla każdy Ingressa za pomocą adnotacji.

W rezultacie zasób Ingress będzie wyglądał mniej więcej tak:

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

W takim przypadku błędy 404 i 502 zostaną przekierowane do usługi error-pages ze wszystkimi niezbędnymi nagłówkami.

В poprzednie wersje Ingress nie miały tej funkcji (fatalne popełnienie na poziomie 0.23). A jeśli w klastrze działają 2 zupełnie różne aplikacje i chcesz określić inną domyślną usługę backendu i przetwarzanie różnych kodów błędów dla każdej z nich, w tym celu będziesz musiał skorzystać z obejść, z których mamy dwa.

Ingres < 0.23: podejście do pierwszego

Ta opcja jest prostsza. Jako aplikacja obsługująca swoje strony mamy zwykły HTML, który nie wie jak patrzeć na nagłówki i zwracać poprawne kody odpowiedzi. Taka aplikacja jest wdrażana za pomocą Ingress z adresu URL /error-pagesi w katalogu ws będzie zwróconym kodem HTML.

Ilustracja w 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

Usługa dla tego wdrożenia musi być typu ClusterIP.

Jednocześnie w aplikacji, w której będziemy przetwarzać błąd, w Ingress dodajemy fragment serwera lub fragment konfiguracji o następującej treści:

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

Ingres < 0.23: drugie podejście

Opcja dla aplikacji, która może przetwarzać nagłówki... I ogólnie jest to bardziej poprawny sposób, zapożyczony z niestandardowych błędów http. Użycie go ręcznie (kopiowanie) pozwoli Ci nie zmieniać ustawień globalnych.

Kroki są następujące. Tworzymy to samo wdrożenie z aplikacją, która potrafi odsłuchać niezbędne nagłówki i poprawnie odpowiedzieć. Dodaj fragment kodu serwera do aplikacji Ingress z następującą treścią:

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

Jak widać, dla każdego błędu, który chcemy przetworzyć, musimy stworzyć własną lokalizację, w której zostaną wstawione wszystkie niezbędne nagłówki, tak jak w „natywnym”. niestandardowe strony błędów. W ten sposób możemy tworzyć różne spersonalizowane strony błędów nawet dla poszczególnych lokalizacji i serwerów.

PS

Inne z serii porad i trików K8s:

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz