Nginx入口和重写目标 [英] nginx ingress & rewrite-target

查看:115
本文介绍了Nginx入口和重写目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Pod,可以响应对/api/

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

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

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

这篇关于Nginx入口和重写目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆