Trucs et astuces Kubernetes: pages d'erreur personnalisées dans NGINX Ingress



Dans cet article, je veux parler de deux fonctionnalités NGINX Ingress liées à l'affichage des pages d'erreur personnalisées, ainsi que des limitations qui existent et des moyens de les contourner.

1. Changer le backend par défaut


Par défaut, NGINX Ingress utilise le backend par défaut, qui exécute la fonction correspondante. Cela signifie que lorsque nous interrogeons Ingress avec un hôte qui n'est pas dans les ressources Ingress, nous obtenons une page avec un code de réponse 404:



Cependant, de plus en plus souvent, nos clients viennent avec une demande au lieu du 404 standard pour montrer leur page avec un logo d'entreprise et d'autres commodités. Pour ce faire, NGINX Ingress a une capacité intégrée de remplacer le default-backend-service . L'option du même nom, en tant qu'argument, est namespace/servicename enregistrement au format namespace/servicename . Le port de service doit être 80.

Pour ce faire, créez votre propre pod (déploiement) et service avec votre application ( un exemple d'implémentation en YAML du référentiel ingress-nginx), qui sera donné à la place du backend par défaut.

Voici une petite illustration:

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

Ainsi, tous les domaines qui ne sont pas explicitement créés via YAML avec kind: Ingress tombent dans le backend par défaut. Dans la liste ci-dessus, sadsdasdas devenu ce domaine.

2. Traitement des erreurs HTTP dans l'application à l'aide du backend par défaut


Une autre situation concerne les requêtes à l'application qui se terminent par des erreurs HTTP (404, 500, 502 ...), dans lesquelles de telles situations ne sont pas traitées (les belles pages correspondantes ne sont pas générées). Cela peut également être dû au désir des développeurs de fournir les mêmes pages d'erreur dans de nombreuses applications.

Pour implémenter ce cas côté serveur, nous avons besoin de:

  1. Suivez les instructions ci-dessus de l'article sur le backend par défaut;
  2. Ajoutez la clé custom-http-errors à la configuration ConfigMap nginx-ingress, par exemple, avec la valeur 404,503 (évidemment, elle correspond aux codes d'erreur couverts par la nouvelle règle).

Le résultat attendu est atteint: lorsque l'application cliente est en cours d'exécution et reçoit une erreur avec un code de réponse de 404 ou 503, la demande sera automatiquement redirigée vers le nouveau backend par défaut ...

Cependant, lors du développement d'une application pour le backend par défaut et les erreurs http personnalisées, vous devez considérer une fonctionnalité importante:

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

Le fait est que lors de la redirection d'une demande, les en-têtes contiendront des informations utiles avec le code de réponse précédent et des informations supplémentaires (une liste complète d'entre elles est disponible ici ).

Cela signifie que vous devez vous-même prendre soin du bon code de réponse . Voici un exemple tiré de la documentation de son fonctionnement.

Vers différentes applications - backend par défaut différent


Pour que la solution ne soit pas globale pour l'ensemble du cluster, mais s'applique uniquement à des applications spécifiques, vous devez d'abord vérifier la version d'Ingress. S'il correspond à 0,23 ou plus , utilisez les annotations natives Ingress:

  1. Nous pouvons redéfinir default-backend par default-backend pour chaque entrée au moyen de l'annotation ;
  2. Nous pouvons remplacer custom-http-errors pour chaque entrée à l' aide d'annotations .

Par conséquent, la ressource Ingress ressemblera à ceci:

 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 

Dans ce cas, les erreurs 404 et 502 seront redirigées vers le service de pages d'erreur avec tous les en-têtes nécessaires.

Dans les versions précédentes d'Ingress, cela n'était pas possible (le commit fatidique à 0,23 ). Et si vous avez 2 applications complètement différentes en cours d'exécution dans votre cluster et que vous souhaitez spécifier un service backend par défaut différent et gérer différents codes d'erreur pour chacune d'entre elles - vous devrez utiliser des solutions de contournement pour cela, dont nous en avons deux.

Entrée <0,23: approche un


Cette option est plus simple. En tant qu'application qui donne ses pages, nous avons du HTML régulier, qui ne sait pas regarder les en-têtes et donner les bons codes de réponse. Une telle application est déployée avec Ingress avec url /error-pages , et le HTML sera donné dans le répertoire ws .

Illustration 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 

Le service pour ce déploiement doit être de type ClusterIP.

Dans le même temps, dans l'application où nous traiterons l'erreur, dans Ingress, nous ajoutons un extrait de serveur ou un extrait de configuration avec le contenu suivant:

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

Entrée <0,23: approche deux


Une option pour une application capable de gérer les en-têtes ... Quoi qu'il en soit, c'est un chemin plus correct, emprunté aux erreurs http-custom. L'utiliser manuellement (copie) vous permettra de ne pas modifier les paramètres globaux.

Les étapes sont les suivantes. Nous créons le même déploiement avec une application qui peut écouter les en-têtes nécessaires et répondre correctement. Ajoutez des applications d'extrait de serveur à Ingress avec le contenu suivant:

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

Comme vous pouvez le voir, pour chaque erreur que nous voulons gérer, vous devez créer votre emplacement, où tous les en-têtes nécessaires seront remplacés, comme dans les pages d'erreur personnalisées "natives". Nous pouvons donc créer différentes pages personnalisées avec des erreurs, même pour des emplacements et des serveurs individuels.

PS


Autres du cycle de trucs et astuces de K8:


Lisez aussi dans notre blog:

Source: https://habr.com/ru/post/fr445596/


All Articles