
In dit artikel wil ik het hebben over twee mogelijkheden van NGINX Ingress met betrekking tot het weergeven van gepersonaliseerde foutpagina's, evenals de bestaande beperkingen en manieren om deze te omzeilen.
1. Wijzigen van de standaard backend
Standaard gebruikt NGINX Ingress de default backend, die deze functie vervult. Dit betekent dat wanneer er een Ingress-aanroep wordt gedaan met een host die niet in de Ingress-resources staat, we een pagina met statuscode 404 ontvangen:
![]()
Echter, steeds vaker komen onze klanten met het verzoek om in plaats van de standaard 404 hun eigen pagina met het bedrijfslogo en andere gemakken weer te geven. Hiervoor heeft NGINX Ingress een om default-backend-servicete overschrijven. We geven de naam van de optie door als argument in het formaat namespace/servicename. De poort van de service moet 80 zijn.
Hiervoor is het nodig om je eigen pod (deployment) en service met jouw applicatie te creëren ( uit de repository ingress-nginx), die zal worden weergegeven in plaats van de default backend.
Hier is een kleine illustratie:
~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 Niet Gevonden
Datum: Ma, 11 Mrt 2019 05:38:15 GMT
Inhoudstype: *
Transfer-Encoding: chunked
Verbinden: keep-alive
<span>De pagina die je zoekt kon niet worden gevonden.</span> Op deze manier komen alle domeinen die niet expliciet zijn aangemaakt via YAML met kind: Ingress, in de default-backend terecht. In de bovenstaande opsomming werd zo'n domein sadsdasdas.
2. Het afhandelen van HTTP-fouten in de applicatie door de default backend
Een andere situatie is het eindigen van HTTP-fouten (404, 500, 502…) voor aanvragen aan de applicatie, waarin dergelijke situaties niet worden afgehandeld (er worden geen overeenkomstige mooie pagina's gegenereerd). Dit kan ook voortkomen uit de wens van ontwikkelaars om dezelfde foutpagina's weer te geven in meerdere applicaties.
Voor de implementatie van dit scenario aan de serverzijde moeten we:
- De instructie hierboven uit het punt over de default backend uitvoeren;
- Toevoegen van de sleutel
custom-http-errorsaan de configuratie ConfigMap nginx-ingress, bijvoorbeeld met de waarde404,503(duidelijk overeenkomend met de foutcodes waarop de nieuwe regel van toepassing is).
Het verwachte resultaat is behaald: bij het werken met de client-applicatie en het ontvangen van een fout met statuscode 404 of 503 wordt de aanvraag automatisch doorgestuurd naar de nieuwe default backend…
Echter, bij het ontwikkelen van de applicatie voor de default backend en custom-http-errors moet een belangrijke eigenschap in overweging worden genomen:
!!! Belangrijk De aangepaste backend wordt verwacht de juiste HTTP-statuscode in plaats van 200 terug te geven. NGINX wijzigt de respons niet van de aangepaste default backend.Het punt is dat bij het omleiden van een verzoek in de headers nuttige informatie zal zijn met de vorige antwoordcode en aanvullende informatie (de volledige lijst is beschikbaar) ).
Dit betekent dat je zelf moet zorgen voor de correcte antwoordcode. uit de documentatie, hoe dit werkt.
Verschillende applicaties — verschillende default backends
Om te voorkomen dat de oplossing globaal is voor de hele cluster, maar alleen betrekking heeft op specifieke applicaties, moet je eerst de versie van Ingress controleren. Als deze overeenkomt met 0.23 of hoger, maak gebruik van de 'native' annotaties van Ingress:
- We kunnen de
default-backendvoor van elke Ingress met ; - We kunnen de
custom-http-errorsvoor van elke Ingress met .
Als resultaat zal de Ingress-resource er ongeveer zo uitzien:
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: 80In dit geval zullen fouten 404 en 502 worden omgeleid naar de service error-pages met alle benodigde headers.
In in eerdere versies van Ingress was deze mogelijkheid er niet (). En als je in je cluster 2 totaal verschillende applicaties hebt en je wilt voor elk van hen verschillende default-backend-services en de afhandeling van verschillende foutcodes aangeven — dan moet je gebruikmaken van workarounds, waarvan we er twee hebben.
Ingress < 0.23: aanpak één
Deze optie is eenvoudiger. Als applicatie die zijn pagina's serveert, hebben we gewone HTML, die niet kijkt naar headers en geen correcte antwoordcodes kan geven. Een dergelijke applicatie wordt gelanceerd met Ingress met de url /error-pages, en in de directory ws zal de te serveren HTML liggen.
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: 80De service voor deze deployment moet van het type ClusterIP zijn.
In de applicatie waar we de fout gaan verwerken, voegen we in de Ingress de server-snippet of configuration-snippet 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
Optie voor een applicatie die in staat is om headers te verwerken… Dit is überhaupt een meer correcte aanpak, overgenomen van custom-http-errors. Handmatig gebruik (kopiëren) zorgt ervoor dat globale instellingen niet gewijzigd worden.
De stappen zijn als volgt. We creëren met een applicatie die in staat is om de benodigde headers te beluisteren en correct te reageren. We voegen in het Ingress van de applicatie een server-snippet toe 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 te zien is, voor elke fout die we willen verwerken, moet er een eigen locatie worden gemaakt, waar alle benodigde headers worden ingevoegd, zoals in de "native" . Op deze manier kunnen we verschillende gepersonaliseerde foutpagina's maken, zelfs voor afzonderlijke locaties en servers.
P.S.
Andere uit de K8s tips & tricks serie:
- «»;
- «»;
- «»;
- «».
Lees ook op onze blog:
- «»;
- «».
Bron: habr.com
