Këshilla dhe truka për Kubernetes: faqet e personalizuara të gabimeve në NGINX Ingress

Kubernetes tips & tricks: faqet e personalizuara të gabimeve në NGINX Ingress

Në këtë artikull, dua të flas për dy mundësi të NGINX Ingress, të lidhura me shfaqjen e faqeve të personalizuara me gabime, si dhe për kufizimet që ekzistojnë në to dhe mënyrat për t'i anashkaluar ato.

1. Ndryshimi i backendit të paracaktuar

Në mënyrë të paracaktuar, NGINX Ingress përdor backendin default, i cili përmbush funksionin përkatës. Kjo do të thotë se kur kërkohet Ingress me një host që nuk ekziston në burimet e Ingress, ne marrim një faqe të tillë me kodin e përgjigjes 404:

Kubernetes tips & tricks: faqet e personalizuara të gabimeve në NGINX Ingress

Megjithatë, gjithnjë e më shpesh klientët tanë vijnë me një kërkesë për të shfaqur faqen e tyre me logon e markës dhe lehtësira të tjera në vend të standardit 404. Për këtë, NGINX Ingress ofron një mundësi të integruar për të rivendosur default-backend-service. Argumentin e opsionit të njëjtë e kalojmë si një regjistër në formatin namespace/servicename. Porta e shërbimit duhet të jetë 80.

Për këtë, është e nevojshme të krijoni pod-in tuaj (deployment) dhe shërbimin me aplikacionin tuaj (shembuj implementimi në YAML nga depoja ingress-nginx), i cili do t'i jepet në vend të backendit të paracaktuar.

Ja një ilustrim i vogël:

~$ 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>Faqja që po kërkoni nuk mund të gjendet.</span>

Kështu që, të gjitha domenet që nuk janë krijuar në mënyrë eksplicite përmes YAML me kind: Ingress, bien në backendin default. Në listën e mësipërme, një domen i tillë ishte sadsdasdas.

2. Trajtimi i gabimeve HTTP në aplikacion nga backend-i default

Një situatë tjetër është që kërkesat që përfundojnë me gabime HTTP (404, 500, 502…) kthehen nga aplikacioni, në të cilin këto situata nuk trajtohen (nuk gjenerohen faqe të përshtatshme). Kjo mund të shkaktohet gjithashtu nga dëshira e zhvilluesve për të ofruar të njëjtat faqe gabimesh në shumë aplikacione.

Për të realizuar këtë rast në anën server, ne kemi nevojë për:

  1. Të ekzekutojmë instruksionin e mësipërm nga pika mbi backendin default;
  2. Të shtojmë në ConfigMap-in e konfigurimit të nginx-ingress çelësin custom-http-errors, për shembull, me vlerën 404,503 (sigurisht, përputhet me kodet e gabimeve, për të cilat zbatohen rregulli i ri).

Rezultati i pritur është arritur: gjatë funksionimit të aplikacionit të klientit dhe marrjes së një gabimi me kodin e përgjigjes 404 ose 503, kërkesa do të drejtsohet automatikisht në backendin e ri default…

Megjithatë, kur zhvilloni aplikacionin për backendin default dhe custom-http-errors, duhet të merrni parasysh një veçori të rëndësishme:

!!! E rëndësishme Backend-i i personalizuar pritet të kthejë kodin e saktë të statusit HTTP në vend të 200. NGINX nuk e ndryshon përgjigjen nga backend-i i personalizuar.

Kjo është, kur kërkesa drejtohet, në tituj do të ketë informacion të dobishëm me kodin e mëparshëm të përgjigjes dhe informacion shtesë (lista e plotë e tyre është e disponueshme këtu).

Kjo do të thotë se duhet të kryerit të kujdeseni për kodin e saktë të përgjigjes. Ja një shembull nga dokumentacioni, si funksionon.

Aplikacione të ndryshme — backend-i i ndryshëm default

Që zgjidhja të mos ishte globale për tërë klasterin, por të përfshinte vetëm aplikacione të veçanta, fillimisht duhet të kontrolloni versionin e Ingress. Nëse ai është 0.23 ose më lart, përdorini anotacionet "nativë" të Ingress:

  1. Ne mund të rivendosim backendin default për çdo të Ingress me anotacionin;
  2. Ne mund të rivendosim custom-http-errors për çdo të Ingress me anotacionin.

Si pasojë, burimi i Ingress do të duket përafërsisht kështu:

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ë këtë rast, gabimet 404 dhe 502 do të drejtohen në shërbimin error-pages me të gjithë titujt e nevojshëm.

në versionet e mëparshme të Ingress kjo mundësi nuk ekzistonte (komenti fatlum në 0.23). Dhe nëse në klasterin tuaj funksionojnë dy aplikacione krejtësisht të ndryshme dhe dëshironi të përcaktoni backendet e ndryshme për çdo një prej tyre dhe të trajtoni kode të ndryshme gabimi — për këtë do t'ju duhet të përdorni workaround-e, të cilat kemi dy.

Ingress < 0.23: qasja e parë

Ky variant është më i thjeshtë. Si aplikacion që jep faqet e tij, kemi një HTML të zakonshëm, i cili nuk di të shikojë titujt dhe të japë kodet e saktë të përgjigjes. Një aplikacion i tillë del me Ingress me url /error-pages, dhe në katalogun ws do të ketë HTML-në që do të jepet.

Ilustrimi 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

Shërbimi për këtë deploy duhet të jetë me tipin ClusterIP.

Në këtë rast, në aplikacionin ku do të trajtojmë gabimin, në Ingress shtojmë server-snippet ose configuration-snippet me përmbajtjen e mëposhtme:

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: alternativa e dytë

Një opsion për një aplikacion që di të обработojë başhabilatorët... Dhe në përgjithësi, kjo është një rrugë më e saktë, e huazuar nga custom-http-errors. Përdorimi i tij manual (kopjimi) do të lejojë të mos ndryshoni cilësimet globale.

Hapat janë si në vijim. Krijojmë një deployment të ngjashëm me një aplikacion që di të dëgjojë başhabilatorët e nevojshëm dhe t'iu përgjigjet siç duhet. Shtojmë në Ingress të aplikacionit server-snippet me përmbajtjen e mëposhtme:

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

Siç duket, për çdo gabim që dua të trajtoj, duhet të krijoj një location të vetme, ku do të vendosen të gjithë başhabilatorët e nevojshëm, si në "original" custom-error-pages. Kështu mund të krijojmë faqe të ndryshme të personalizuara për gabime edhe për location të veçanta dhe servera.

P.S.

Diçka tjetër nga cikli K8s tips & tricks:

Lexoni gjithashtu në blogun tonë:

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster