Consells i trucs de Kubernetes: pàgines d'error personalitzades a NGINX Ingress

Consells i trucs de Kubernetes: pàgines d'error personalitzades a NGINX Ingress

En aquest article, vull parlar de dues característiques de NGINX Ingress relacionades amb la visualització de pàgines d'error personalitzades, així com de les seves limitacions i maneres d'evitar-les.

1. Canvieu el backend predeterminat

De manera predeterminada, NGINX Ingress utilitza el backend predeterminat, que realitza la funció corresponent. Això vol dir que quan sol·licitem un Ingress amb un host que no es troba als recursos Ingress, obtenim aquesta pàgina amb un codi de resposta 404:

Consells i trucs de Kubernetes: pàgines d'error personalitzades a NGINX Ingress

No obstant això, cada cop més sovint, els nostres clients vénen amb una sol·licitud per mostrar la seva pàgina amb el logotip de l'empresa i altres comoditats en lloc de l'estàndard 404. Per a això, NGINX Ingress té capacitat integrada redefinir default-backend-service. Passem el registre de format com a argument a l'opció del mateix nom namespace/servicename. El port de servei ha de ser 80.

Per fer-ho, heu de crear el vostre propi pod (desplegament) i un servei amb la vostra aplicació (exemple d'implementació a YAML des del dipòsit ingress-nginx), que es donarà en lloc del backend predeterminat.

Aquí teniu una petita il·lustració:

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

Així, tots els dominis que no es creen explícitament mitjançant YAML amb kind: Ingress, cau al backend predeterminat. A la llista anterior, aquest domini es va convertir en sadsdasdas.

2. Gestió d'errors HTTP a l'aplicació pel backend predeterminat

Una altra situació són les sol·licituds que acaben amb errors HTTP (404, 500, 502...) a una aplicació que no gestiona aquestes situacions (no es generen les pàgines boniques corresponents). També pot ser causat pel desig dels desenvolupadors de tornar les mateixes pàgines d'error en diverses aplicacions.

Per implementar aquest cas al costat del servidor, necessitem:

  1. Seguiu les instruccions anteriors del paràgraf sobre el backend predeterminat;
  2. Afegiu la clau a la configuració ConfigMap nginx-ingress custom-http-errors, per exemple, amb el valor 404,503 (òbviament coincideix amb els codis d'error coberts per la nova regla).

S'aconsegueix el resultat esperat: quan l'aplicació client s'està executant i rep un error amb un codi de resposta 404 o 503, la sol·licitud es redirigirà automàticament al nou backend predeterminat...

Tanmateix, quan es desenvolupi una aplicació per al backend predeterminat i els errors de http personalitzats, cal tenir en compte una característica important:

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

El fet és que quan es redirigeix ​​la sol·licitud, les capçaleres contindran informació útil amb el codi de resposta anterior i informació addicional (la seva llista completa està disponible aquí).

Això vol dir que cal tenir cura del codi de resposta correcte. Aquest és un exemple de la documentació com funciona.

Diferents aplicacions: backend predeterminat diferent

Perquè la solució no sigui global per a tot el clúster, sinó que s'apliqui només a aplicacions específiques, primer heu de comprovar la versió d'Ingress. Si coincideix 0.23 o més, utilitzeu les anotacions d'entrada natives:

  1. Podem redefinir default-backend per de cadascuna Ingress'a anotació;
  2. Podem redefinir custom-http-errors per de cadascuna Ingress'a anotació.

Com a resultat, el recurs Ingress tindrà un aspecte semblant a això:

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

En aquest cas, els errors 404 i 502 es redirigiran al servei de pàgines d'error amb totes les capçaleres necessàries.

В les versions anteriors d'Ingress no tenien aquesta funció. (cometre fatídic en 0.23). I si teniu 2 aplicacions completament diferents en execució al vostre clúster i voleu especificar diferents serveis de backend predeterminats i gestionar diferents codis d'error per a cadascuna d'elles, haureu d'utilitzar solucions alternatives, de les quals en tenim dos.

Entrada < 0.23: apropar-se a un

Aquesta opció és més senzilla. Com a aplicació que representa les seves pàgines, tenim HTML senzill, que no sap mirar les capçaleres i retornar els codis de resposta correctes. Aquesta aplicació es desplega amb Ingress amb url /error-pages, i al directori ws se li donarà HTML.

Il·lustració en 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

El servei per a aquest desplegament ha de ser del tipus ClusterIP.

Paral·lelament, a l'aplicació on gestionarem l'error, a Ingress afegim server-snippet o configuration-snippet amb el següent contingut:

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

Entrada < 0.23: segona aproximació

Una variant per a una aplicació que pot processar capçaleres... I, en general, aquesta és una manera més correcta, agafada de custom-http-errors. Utilitzar-lo manualment (copiar) us permetrà no canviar la configuració global.

Els passos són els següents. Creem mateix desplegament amb una aplicació que pot escoltar les capçaleres correctes i respondre correctament. Afegim aplicacions de fragments de servidor a l'Ingress amb el contingut següent:

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

Com podeu veure, per a cada error que volem processar, hem de fer la nostra pròpia ubicació, on es substituiran totes les capçaleres necessàries, com en "natiu" pàgines d'error personalitzades. D'aquesta manera podem crear diferents pàgines d'error personalitzades fins i tot per a ubicacions i servidors individuals.

PS

Altres de la sèrie de trucs i consells K8s:

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari