Kubernetes tipy & triky: personalizované stránky chýb v NGINX Ingress

Kubernetes tipy a triky: personalizované chybové stránky v NGINX Ingress

V tomto článku sa chcem podeliť o dve možnosti NGINX Ingress, ktoré súvisia s vykresľovaním personalizovaných stránok s chybami, ako aj o obmedzeniach a spôsoboch ich obídenia.

1. Zmena predvoleného backendu

Predvolene NGINX Ingress používa default backend, ktorý vykonáva zodpovedajúcu funkciu. To znamená, že pri požiadavke Ingressu so zadaným hostiteľom, ktorý nie je v zdrojoch Ingressu, dostaneme stránku s kódom odpovede 404:

Kubernetes tipy a triky: personalizované chybové stránky v NGINX Ingress

Čoraz častejšie sa však naši zákazníci obracajú s požiadavkou, aby namiesto štandardného 404 zobrazili svoju stránku s logom a ďalšími pohodlnými prvkami. Na to má NGINX Ingress vstavanú možnosť prepisovať default-backend-service. Ako argument predávame rovnakú voľbu vo formáte namespace/servicename. Port služby by mal byť 80.

Na to je potrebné vytvoriť svoj vlastný pod (deployment) a službu s vašou aplikáciou (príklad realizácie v YAML z repozitára ingress-nginx), ktorá bude poskytovaná namiesto default backendu.

Tu je malá ilustrácia:

~$ 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>Stránka, ktorú hľadáte, sa nenašla.</span>

Takže všetky domény, ktoré explicitne neboli vytvorené cez YAML s kind: Ingress, prechádzajú do default-backend. V uvedenom zozname takouto doménou bola sadsdasdas.

2. Spracovanie HTTP chýb v aplikácii pomocou default backendu

Iná situácia — požiadavky na aplikáciu, ktoré končia HTTP chybami (404, 500, 502…) a v ktorej sa takéto situácie neprepracúvajú (negenerujú sa príslušné pekné stránky). To môže byť spôsobené aj snahou vývojárov poskytovať rovnaké chyby stránky v mnohých aplikáciách.

Na realizáciu tohto prípadu na strane servera potrebujeme:

  1. Postupovať podľa pokynov vyššie z bodu o default backend;
  2. Do konfiguračného ConfigMap nginx-ingress pridať kľúč custom-http-errors, napríklad s hodnotou 404,503 (obviously corresponds to the error codes to which the new rule applies).

Očakávaný výsledok bol dosiahnutý: pri práci klientskej aplikácie a prijatí chyby s kódom odpovede 404 alebo 503 bude požiadavka automaticky presmerovaná na nový default backend…

Avšak pri vývoji aplikácie pre default backend a custom-http-errors treba zohľadniť dôležitú vlastnosť:

!!! Dôležité Očakáva sa, že prispôsobený backend vráti správny HTTP stavový kód namiesto 200. NGINX nemení odpoveď z prispôsobeného default backendu.

Ide o to, že pri presmerovaní žiadosti v hlavičkách bude užitočná informácia s predchádzajúcim kódom odpovede a doplnkovými informáciami (ich úplný zoznam je k dispozícii tu).

To znamená, že sa o to musíte postarať vy sami správnym kódom odpovede. Tu je príklad z dokumentácie, ako to funguje.

Rôznym aplikáciám prislúcha rôzny predvolený backend

Aby riešenie nebolo globálne pre celý klaster, ale týkalo sa iba konkrétnych aplikácií, najprv je potrebné skontrolovať verziu Ingress. Ak zodpovedá 0.23 alebo vyššie, použite "rodné" anotácie Ingress:

  1. Môžeme predefinovať default-backend pre každú Ingressu s pomocou anotácie;
  2. Môžeme predefinovať custom-http-errors pre každú Ingressu s pomocou anotácie.

Výsledkom bude, že zdroj Ingress bude vyzerať asi 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 takom prípade budú chyby 404 a 502 presmerované na službu error-pages so všetkými potrebnými hlavičkami.

V v predchádzajúcich verziách Ingress neexistovala táto možnosť (osudový commit v 0.23). A ak vo vašom klastri bežia 2 úplne odlišné aplikácie a chcete pre každú z nich uviesť rôzne predvolené backendové služby a spracovanie rôznych kódov chýb — na to budete musieť použiť workaroundy, ktorých máme dva.

Ingress < 0.23: prvý prístup

Tento variant je jednoduchší. Ako aplikáciu, ktorá vydáva svoje stránky, máme obyčajný HTML, ktorý nie je schopný pozerať sa na hlavičky a vracať správne kódy odpovede. Taká aplikácia sa nasadí s Ingressom s URL /error-pages, a v adresári ws bude ležať vydávaný HTML.

Ilustrácia 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 pre toto nasadenie by mala byť typu ClusterIP.

Pri tom v aplikácii, kde budeme spracovávať chybu, v Ingress pridávame server-snippet alebo configuration-snippet s nasledujúcim obsahom:

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á prístupnosť

Možnosť pre aplikáciu, ktorá dokáže spracovávať hlavičky… A vlastne je to oveľa správnejší spôsob, prevzatý z custom-http-errors. Jej manuálne použitie (kopírovanie) umožní nezmeniť globálne nastavenia.

Kroky sú nasledovné. Vytvoríme rovnaký deployment s aplikáciou, ktorá dokáže počúvať požadované hlavičky a správne reagovať. Pridáme do Ingress aplikácie server-snippet s nasledujúcim obsahom:

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

Ako vidno, pre každú chybu, ktorú chceme spracovávať, je potrebné vytvoriť vlastné location, kde sa zavedú všetky potrebné hlavičky, tak ako v „nativnom“ custom-error-pages. Takto môžeme vytvárať rôzne personalizované stránky s chybami aj pre jednotlivé locationy a servery.

P.S.

Ďalšie z cyklu K8s tips & tricks:

Prečítajte si tiež na našom blogu:

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster