
V tem članku želim spregovoriti o dveh možnostih NGINX Ingress, povezanih z oblikovanjem personaliziranih strani napak, ter o obstoječih omejitvah in načinov, kako jih obiti.
1. Sprememba privzetega backend-a
Privzeto NGINX Ingress uporablja default backend, ki opravlja ustrezno nalogo. To pomeni, da ob zahtevi Ingress-a z navedbo gostitelja, ki ni v virih Ingress, prejmemo stran s kodo odgovora 404:
![]()
Vendar pa vse pogosteje naši naročniki prihajajo s prošnjo, da namesto standardnega 404 prikažemo svojo stran s logotipom in drugimi udobnostmi. Za to ima NGINX Ingress prekoračiti default-backend-service. Kot argument prehodimo zapis v formatu namespace/servicename. Port storitve mora biti 80.
Zato je potrebno ustvariti svoj pod (deployment) in storitev z vašo aplikacijo ( iz repozitorija ingress-nginx), ki bo prikazana namesto default backend.
Tukaj je majhna ilustracija:
~$ 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>Stran, ki jo iščete, ni bila najdena.</span> Tako vsi domene, ki niso izrecno ustvarjene preko YAML z kind: Ingress, spadajo v default-backend. V seznamu zgoraj je takšna domena sadsdasdas.
2. Obdelava HTTP napak v aplikaciji z uporabo default backend-a
Druga situacija je, ko zahtevki do aplikacije končajo z HTTP napakami (404, 500, 502…) in v njej takšne situacije niso obdelane (ustrezne lepe strani se ne generirajo). To lahko izhaja tudi iz želje razvijalcev, da vodijo enotne strani napak v več aplikacijah.
Za uresničitev tega primera na strežniški strani moramo:
- Izvesti zgornja navodila iz točke o default backend;
- V konfiguracijski ConfigMap nginx-ingress dodati ključ
custom-http-errors, na primer, z vrednostjo404,503(očitno se nanaša na kode napak, na katere se novo pravilo razteza).
Želeni rezultat je dosežen: ob delu odjemalske aplikacije in prejemanju napake s kodo odgovora 404 ali 503 se bo zahteva samodejno preusmerila v nov default backend…
Vendar pa je pri razvoju aplikacije za default backend in custom-http-errors potrebno upoštevati pomembno značilnost:
!!! Pomembno Od prilagojenega backend-a se pričakuje, da vrne pravilno HTTP statusno kodo namesto 200. NGINX ne spremeni odgovora iz prilagojenega default backend-a.Grese je u tome što će prilikom preusmjeravanja zahtjeva biti korisne informacije u zaglavljima s prethodnim kodom odgovora i dodatnim informacijama (cijeli njihov popis je dostupan ).
To znači da se sami morate pobrinuti za ispravan kod odgovora. iz dokumentacije, kako to funkcionira.
Raznim aplikacijama odgovara različiti default backend
Kako rješenje ne bi bilo globalno za cijeli klaster, već se odnosilo samo na određene aplikacije, prvo treba provjeriti verziju Ingress-a. Ako odgovara 0.23 ili novijoj verziji, iskoristite „nativne“ anotacije Ingress-a:
- Možemo redefinirati
default-backendza svaki Ingress-a pomoću ; - Možemo redefinirati
custom-http-errorsza svaki Ingress-a pomoću .
Kao rezultat, resurs Ingress-a će izgledati otprilike ovako:
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: 80U tom slučaju, greške 404 i 502 će biti preusmjerene na servis error-pages sa svim potrebnim zaglavljima.
V u prethodnim verzijama Ingress-a ta mogućnost nije postojala (). Ako u vašem klasteru rade 2 potpuno različite aplikacije i želite za svaku od njih odrediti različite default-backend-servise i za obradu različitih kodova grešaka — za to će biti potrebno koristiti workaround-e, kojih imamo dva.
Ingress < 0.23: prvi pristup
Ova opcija je jednostavnija. Kao aplikacija koja isporučuje svoje stranice, imamo običan HTML koji ne može gledati na zaglavlja i vraćati ispravne kodove odgovora. Takva aplikacija se koristi s Ingress-om s url-om /error-pages, a u katalogu ws bit će HTML koji se isporučuje.
Ilustracija u YAML-u:
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: 80Servis za ovaj deploy treba biti s tipom ClusterIP.
Pri tome, u aplikaciji gdje ćemo obraditi grešku, dodajemo server-snippet ili configuration-snippet s sljedećim sadržajem:
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: druga opcija
Opcija za aplikaciju koja može obraditi zaglavlja… Uostalom, ovo je ispravniji način koji je preuzet iz custom-http-errors. Njegova ručna upotreba (kopiranje) omogućava da se ne menjaju globalne postavke.
Koraci su sledeći. Kreiramo s aplikacijom koja može slušati potrebna zaglavlja i pravilno odgovoriti. Dodajemo u Ingress aplikacije server-snippet sa sledećim sadržajem:
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;
}Kao što se može videti, za svaku grešku koju želimo obraditi, potrebno je napraviti svoj location gde će se ubacivati svi potrebni zaglavlja, kao u "izvornom" . Tako možemo kreirati različite personalizovane stranice sa greškama čak i za pojedinačne location-e i servere.
P.S.
Još jedan iz serije K8s saveta & trikova:
- «»;
- «»;
- «»;
- «».
Preberite tudi na našem blogu:
- «»;
- «».
Izvor: habr.com
