nginx 入口 &重写目标 [英] nginx ingress & rewrite-target
问题描述
我有一个响应/api/请求的 Pod
I have a pod that responds to requests to /api/
我想做一个重写,其中对/auth/api/的请求转到/api/.
I want to do a rewrite where requests to /auth/api/ go to /api/.
使用 Ingress (nginx),我认为使用 ingress.kubernetes.io/rewrite-target: 注释我可以这样做:
Using an Ingress (nginx), I thought that with the ingress.kubernetes.io/rewrite-target: annotation I could do it something like this:
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
然而,正在发生的事情是/auth/被传递到服务/pod 并且 404 被正确地抛出.我一定是误解了重写注释.
What's happening however is that /auth/ is being passed to the service/pod and a 404 is rightfully being thrown. I must be misunderstanding the rewrite annotation.
有没有办法通过 k8s & 做到这一点?入口?
Is there a way to do this via k8s & ingresses?
推荐答案
我创建了以下有效的示例,我将对其进行解释.要运行这个最小示例,请运行以下命令:
I have created the following example that works and which I will explain. To run this minimal example, run these commands:
$ 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
您会注意到,入口重写注释似乎对尾部斜杠非常挑剔.如果不存在尾部斜杠,则不会重写请求.但是,如果提供了尾部斜杠,则请求 uri 将被重写,您的代理将按预期运行.
As you'll notice, the ingress rewrite annotation appears to be very particular about trailing slashes. If a trailing slash is not present, the request will not be rewritten. However, if a trailing slash is provided, the request uri will be rewritten and your proxy will function as expected.
从入口控制器内部检查生成的 nginx.conf
文件后,负责此行为的代码行是:
After inspecting the generated nginx.conf
file from inside the ingress controller, the line of code responsible for this behavior is:
rewrite /auth/api/(.*) api/$1 break;
这一行告诉我们只有匹配第一个参数的请求才会被第二个参数指定的路径重写.
This line tells us that only requests matching the first argument will be rewritten with the path specified by the second argument.
我相信这是值得的.
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 + "
")
}
func main() {
http.HandleFunc("/", httpHandler)
panic(http.ListenAndServe(":80", nil))
}
这篇关于nginx 入口 &重写目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!