J'ai un pod qui répond aux demandes de/api /
Je veux faire une réécriture où les demandes de/auth/api/aller à/api /.
En utilisant un Ingress (nginx), j'ai pensé qu'avec l'annotation ingress.kubernetes.io/rewrite-target: je pouvais faire quelque chose comme ceci:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- Host: api.myapp.com
http:
paths:
- path: /auth/api
backend:
serviceName: myapi
servicePort: myapi-port
Ce qui se passe cependant, c'est que/auth/est passé au service/pod et un 404 est lancé à juste titre. Je dois mal comprendre l'annotation de réécriture.
Existe-t-il un moyen de le faire via k8s et entrées?
J'ai créé l'exemple suivant qui fonctionne et que je vais expliquer. Pour exécuter cet exemple minimal, exécutez ces commandes:
$ minikube start
$ minikube addons enable ingress # might take a while for ingress pod to bootstrap
$ kubectl apply -f kubernetes.yaml
$ curl https://$(minikube ip)/auth/api/ --insecure
success - path: /api/
$ curl https://$(minikube ip)/auth/api --insecure
failure - path: /auth/api
$ curl https://$(minikube ip)/auth/api/blah/whatever --insecure
success - path: /api/blah/whatever
Comme vous le remarquerez, l'annotation de réécriture d'entrée semble être très particulière à propos des barres obliques de fin. Si une barre oblique de fin n'est pas présente, la demande ne sera pas réécrite. Cependant, si une barre oblique de fin est fournie, l'URI de demande sera réécrit et votre proxy fonctionnera comme prévu.
Après avoir inspecté le fichier nginx.conf
Généré depuis l'intérieur du contrôleur d'entrée, la ligne de code responsable de ce comportement est:
rewrite /auth/api/(.*) api/$1 break;
Cette ligne nous indique que seules les demandes correspondant au premier argument seront réécrites avec le chemin spécifié par le deuxième argument.
Je pense que cela en vaut la peine.
kubernetes.yaml
---
apiVersion: v1
kind: Service
metadata:
name: ingress-rewite-example
spec:
selector:
app: ingress-rewite-example
ports:
- name: nginx
port: 80
protocol: TCP
targetPort: 80
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ingress-rewite-example
spec:
template:
metadata:
labels:
app: ingress-rewite-example
spec:
containers:
- name: ingress-rewite-example
image: fbgrecojr/office-hours:so-47837087
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-rewite-example
annotations:
ingress.kubernetes.io/rewrite-target: /api
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /auth/api
backend:
serviceName: ingress-rewite-example
servicePort: 80
main.go
package main
import (
"fmt"
"strings"
"net/http"
)
func httpHandler(w http.ResponseWriter, r *http.Request) {
var response string
if strings.HasPrefix(r.URL.Path, "/api") {
response = "success"
} else {
response = "failure"
}
fmt.Fprintf(w, response + " - path: " + r.URL.Path + "\n")
}
func main() {
http.HandleFunc("/", httpHandler)
panic(http.ListenAndServe(":80", nil))
}
Je ne sais pas si c'est toujours un problème, mais depuis la version 0.22, il semble que vous ayez besoin d'utiliser des groupes de capture pour passer des valeurs à la valeur de réécriture-cible De l'exemple nginx disponible ici
À partir de la version 0.22.0, les définitions d'entrée utilisant l'annotation nginx.ingress.kubernetes.io/rewrite-target ne sont pas rétrocompatibles avec les versions précédentes. Dans la version 0.22.0 et au-delà, toutes les sous-chaînes de l'URI de demande qui doivent être transmises au chemin réécrit doivent être explicitement définies dans un groupe de capture.
Pour vos besoins spécifiques, quelque chose comme ça devrait faire l'affaire
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapi-ing
annotations:
ingress.kubernetes.io/rewrite-target: /api/$2
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- Host: api.myapp.com
http:
paths:
- path: /auth/api(/|$)(.*)
backend:
serviceName: myapi
servicePort: myapi-port