Tipy a triky Kubernetes: vlastní chybové stránky v NGINX Ingress

Tipy a triky Kubernetes: vlastní chybové stránky v NGINX Ingress

V tomto článku chci mluvit o dvou funkcích NGINX Ingress souvisejících se zobrazováním personalizovaných chybových stránek a také o jejich omezeních a způsobech, jak je obejít.

1. Změňte výchozí backend

Ve výchozím nastavení používá NGINX Ingress výchozí backend, který provádí odpovídající funkci. To znamená, že když požadujete Ingress s hostitelem, který není ve zdrojích Ingress, dostaneme tuto stránku s kódem odpovědi 404:

Tipy a triky Kubernetes: vlastní chybové stránky v NGINX Ingress

Stále častěji však naši klienti přicházejí s požadavkem na zobrazení stránky s firemním logem a dalšími vymoženostmi namísto standardní 404. K tomu má NGINX Ingress vestavěná schopnost předefinovat default-backend-service. Záznam formátu předáme jako argument stejnojmenné volbě namespace/servicename. Servisní port musí být 80.

Chcete-li to provést, musíte vytvořit svůj vlastní modul (nasazení) a službu s vaší aplikací (příklad implementace v YAML z repozitáře ingress-nginx), který bude dán místo výchozího backendu.

Zde je malá ilustrace:

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

Tedy všechny domény, které nejsou explicitně vytvořeny přes YAML s kind: Ingress, spadají do výchozího backendu. Ve výše uvedeném seznamu se tato doména stala sadsdasdas.

2. Zpracování chyb HTTP v aplikaci pomocí výchozího backendu

Jinou situací jsou požadavky končící chybami HTTP (404, 500, 502…) na aplikaci, která takové situace nezvládá (nevygenerují se odpovídající krásné stránky). Může to být také způsobeno přáním vývojářů vracet stejné chybové stránky ve více aplikacích.

K implementaci tohoto případu na straně serveru potřebujeme:

  1. Postupujte podle pokynů výše v odstavci o výchozím backendu;
  2. Přidejte klíč do konfigurace ConfigMap nginx-ingress custom-http-errors, například s hodnotou 404,503 (samozřejmě odpovídá chybovým kódům, na které se vztahuje nové pravidlo).

Je dosaženo očekávaného výsledku: když je klientská aplikace spuštěna a obdrží chybu s kódem odpovědi 404 nebo 503, požadavek bude automaticky přesměrován na nový výchozí backend ...

Při vývoji aplikace pro výchozí backend a vlastní chyby http je však třeba vzít v úvahu důležitou funkci:

!!! 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 je, že když je požadavek přesměrován, záhlaví bude obsahovat užitečné informace s předchozím kódem odpovědi a další informace (jejich úplný seznam je k dispozici zde).

To znamená, že musíte postarejte se o správný kód odpovědi. Zde je příklad. z dokumentace, jak to funguje.

Různé aplikace - jiný výchozí backend

Aby řešení nebylo globální pro celý cluster, ale týkalo se pouze konkrétních aplikací, je potřeba nejprve zkontrolovat verzi Ingress. Pokud se shoduje 0.23 nebo vyšší, použijte nativní anotace Ingress:

  1. Můžeme předefinovat default-backend pro každý Ingress'a anotace;
  2. Můžeme předefinovat custom-http-errors pro každý Ingress'a anotace.

V důsledku toho bude zdroj Ingress vypadat nějak takto:

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

V tomto případě budou chyby 404 a 502 přesměrovány na službu error-pages se všemi potřebnými záhlavími.

В předchozí verze Ingress tuto funkci neměly. (osudový závazek v 0.23). A pokud máte ve svém clusteru spuštěny 2 zcela odlišné aplikace a chcete specifikovat různé výchozí backendové služby a zpracovávat různé chybové kódy pro každou z nich, budete k tomu muset použít zástupná řešení, z nichž máme dvě.

Ingress < 0.23: přiblížit se k jedničce

Tato možnost je jednodušší. Jako aplikaci, která vykresluje své stránky, máme prostý HTML, který neví, jak se dívat na záhlaví a vracet správné kódy odpovědí. Taková aplikace se spustí s Ingress s url /error-pagesa v adresáři ws dostane HTML.

Ilustrace v 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

Služba pro toto nasazení musí být typu ClusterIP.

Zároveň v aplikaci, kde budeme chybu řešit, v Ingress přidáme server-snippet nebo configuration-snippet s následujícím obsahem:

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: druhé přiblížení

Varianta pro aplikaci, která umí zpracovávat hlavičky ... A obecně je to správnější způsob, vypůjčený z custom-http-errors. Ruční použití (kopírování) vám umožní neměnit globální nastavení.

Postup je následující. tvoříme stejné nasazení s aplikací, která dokáže naslouchat správným hlavičkám a správně reagovat. Do Ingress přidáváme aplikace server-snippet s následujícím obsahem:

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 vidíte, pro každou chybu, kterou chceme zpracovat, musíme vytvořit vlastní umístění, kde budou nahrazeny všechny potřebné hlavičky, jako v "nativním" vlastní chybové stránky. Můžeme tak vytvářet různé personalizované chybové stránky i pro jednotlivá umístění a servery.

PS

Další ze série tipů a triků K8s:

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář