Kubernetes tips & tricks: aangepaste foutpagina's in NGINX Ingress

Kubernetes tips & tricks: aangepaste foutpagina's in NGINX Ingress

In dit artikel wil ik het hebben over twee functies van NGINX Ingress die verband houden met het weergeven van gepersonaliseerde foutpagina's, evenals de beperkingen die daarin bestaan ​​en manieren om deze te omzeilen.

1. De standaard backend wijzigen

Standaard gebruikt NGINX Ingress de standaard backend, die de overeenkomstige functie uitvoert. Dit betekent dat wanneer we een Ingress aanvragen waarbij een host wordt opgegeven die niet in de Ingress-bronnen staat, we de volgende pagina ontvangen met een 404-antwoordcode:

Kubernetes tips & tricks: aangepaste foutpagina's in NGINX Ingress

Steeds vaker komen onze klanten echter met het verzoek om hun pagina te tonen met een bedrijfslogo en andere voorzieningen in plaats van de standaard 404. Om dit te doen heeft NGINX Ingress ingebouwde mogelijkheid herdefiniëren default-backend-service. We geven de formaatinvoer door als argument voor de optie met dezelfde naam namespace/servicename. De poort van de service moet 80 zijn.

Om dit te doen, moet u uw eigen pod (implementatie) en service maken bij uw applicatie (voorbeeldimplementatie in YAML uit de ingress-nginx-repository), die wordt gegeven in plaats van de standaard backend.

Hier is een kleine illustratie:

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

Dus alle domeinen die niet expliciet via YAML zijn aangemaakt met kind: Ingress, vallen in de standaard-backend. In de bovenstaande lijst werd dit domein sadsdasdas.

2. HTTP-fouten in de applicatie afhandelen met behulp van de standaard backend

Een andere situatie zijn verzoeken die eindigen op HTTP-fouten (404, 500, 502...) naar een applicatie die dergelijke situaties niet verwerkt (de bijbehorende mooie pagina's worden niet gegenereerd). Dit kan ook te wijten zijn aan de wens van ontwikkelaars om dezelfde foutpagina's in meerdere applicaties weer te geven.

Om dit geval aan de serverkant te implementeren, hebben we het volgende nodig:

  1. Volg de bovenstaande instructies uit de paragraaf over standaard backend;
  2. Voeg een sleutel toe aan de nginx-ingress-configuratie ConfigMap custom-http-errorsbijvoorbeeld met de waarde 404,503 (komt uiteraard overeen met de foutcodes die onder de nieuwe regel vallen).

Het verwachte resultaat is bereikt: wanneer de clientapplicatie draait en een foutmelding ontvangt met responscode 404 of 503, wordt het verzoek automatisch doorgestuurd naar de nieuwe standaard backend...

Wanneer u echter een applicatie ontwikkelt voor standaard backend- en aangepaste http-fouten, moet u rekening houden met een belangrijke functie:

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

Het is een feit dat wanneer een verzoek wordt omgeleid, de headers nuttige informatie zullen bevatten met de vorige responscode en aanvullende informatie (hun volledige lijst is beschikbaar hier).

Dit betekent dat u dat zelf moet doen zorg voor de juiste responscode. Hier is een voorbeeld. uit de documentatie hoe het werkt.

Verschillende applicaties hebben verschillende standaardbackends

Om er zeker van te zijn dat de oplossing niet globaal is voor het hele cluster, maar alleen van toepassing is op specifieke applicaties, moet je eerst de Ingress-versie controleren. Als het overeenkomt 0.23 of hoger, gebruik dan de native Ingress-annotaties:

  1. We kunnen overschrijven default-backend voor elke Ingress's gebruik maken van annotaties;
  2. We kunnen overschrijven custom-http-errors voor elke Ingress's gebruik maken van annotaties.

Als gevolg hiervan ziet de Ingress-bron er ongeveer zo uit:

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

In dit geval worden de fouten 404 en 502 doorgestuurd naar de error-pages-service met alle benodigde headers.

В eerdere versies van Ingress hadden deze functie niet (noodlottige commit op 0.23). En als je 2 totaal verschillende applicaties in je cluster hebt draaien en je wilt voor elk daarvan een andere standaard-backend-service en verwerking van verschillende foutcodes opgeven, dan zul je hiervoor workarounds moeten gebruiken, waarvan we er twee hebben.

Ingress < 0.23: benader één

Deze optie is eenvoudiger. Als applicatie die zijn pagina's bedient, hebben we gewone HTML, die niet weet hoe hij naar de headers moet kijken en de juiste responscodes moet retourneren. Zo’n applicatie wordt uitgerold met Ingress vanaf de url /error-pagesen in de catalogus ws zal de geretourneerde HTML zijn.

Illustratie in 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

De service voor deze implementatie moet van het type ClusterIP zijn.

Tegelijkertijd voegen we in Ingress in de applicatie waarin we de fout verwerken een serverfragment of configuratiefragment toe met de volgende inhoud:

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: tweede benadering

Een optie voor een applicatie die headers kan verwerken... En over het algemeen is dit een correctere manier, ontleend aan custom-http-errors. Als u het handmatig gebruikt (kopiëren), kunt u de algemene instellingen niet wijzigen.

De stappen zijn als volgt. We creëren dezelfde inzet met een applicatie die de nodige krantenkoppen kan beluisteren en correct kan reageren. Voeg een serverfragment toe aan de Ingress-applicatie met de volgende inhoud:

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

Zoals u kunt zien, moeten we voor elke fout die we willen verwerken onze eigen locatie maken, waar alle benodigde headers worden ingevoegd, zoals in de ‘native’. aangepaste foutpagina's. Op deze manier kunnen we verschillende gepersonaliseerde foutpagina's maken, zelfs voor individuele locaties en servers.

PS

Overige uit de K8s tips & tricks serie:

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie