简体   繁体   English

nginx入口子路径重定向

[英]nginx ingress sub path redirection

I have an ingress controller and ingress resource running with all /devops mapped to devopsservice in the backend.我有一个入口控制器和入口资源运行,所有 /devops 都映射到后端的 devopsservice。 When I try to hit " http://hostname/devops " things work and I get a page (although without CSS and styles) with a set of hyperlinks for eg one of them is "logs".当我尝试点击“ http://hostname/devops ”时,一切正常,我得到一个页面(虽然没有 CSS 和样式),其中包含一组超链接,例如其中一个是“日志”。

When I click on the "logs" hyperlink, it is redirecting me to http://hostname/logs whereas I need it to be http://hostname/devops/logs .当我点击“日志”超链接时,它会将我重定向到http://hostname/logs而我需要它是http://hostname/devops/logs

Any idea what I can do?知道我能做什么吗?

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: my-ingress
 namespace: ingress-nginx
 annotations:
   kubernetes.io/ingress.class: nginx
   nginx.ingress.kubernetes.io/rewrite-target: /
   nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
 rules:
 - host: master1.dev.local
   http:
     paths:
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops

Looks like your ingress is not serving anything /devops/* .看起来您的入口没有提供任何服务/devops/* Try adding another path /devops/* with the same backend.尝试使用相同的后端添加另一个路径/devops/* Basically this:基本上是这样的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: my-ingress
 namespace: ingress-nginx
 annotations:
   kubernetes.io/ingress.class: nginx
   nginx.ingress.kubernetes.io/rewrite-target: /
   nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
 rules:
 - host: master1.dev.local
   http:
     paths:
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops/*
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops

Update: the above has been deprecated in favor of something like this:更新:以上内容已被弃用,以支持以下内容:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: master1.dev.local
    http:
      paths:
      - backend:
          serviceName: devops1
          servicePort: 10311
        path: /devops(/|$)(.*)

If you access http://hostname/devops/logs directly from your browser, certainly you will get what you want.如果您直接从浏览器访问http://hostname/devops/logs ,您肯定会得到您想要的。 But since you click the hyperlink in the homepage, then you can only get http://hostname/logs , which will be certainly failed.但是既然你点击了首页的超链接,那么你只能得到http://hostname/logs ,肯定会失败。

So, you need /logs backend configured in your ingress yaml to get it processed, and configure nginx.ingress.kubernetes.io/configuration-snippet to ensure /logs not get rewrote, like this:因此,您需要在 ingress yaml 中配置/logs后端以对其进行处理,并配置nginx.ingress.kubernetes.io/configuration-snippet以确保/logs不会被重写,如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: my-ingress
 namespace: ingress-nginx
 annotations:
   kubernetes.io/ingress.class: nginx
   nginx.ingress.kubernetes.io/rewrite-target: /
   nginx.ingress.kubernetes.io/add-base-url : "true"
   nginx.ingress.kubernetes.io/configuration-snippet: |
     rewrite ^/logs /logs break;
spec:
 rules:
 - host: master1.dev.local
   http:
     paths:
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /logs
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops

The nginx.ingress.kubernetes.io/x-forwarded-prefix annotation can be used for this purpose. nginx.ingress.kubernetes.io/x-forwarded-prefix 注释可用于此目的。

It adds x-forwarded-prefix header to http request with a value from this annotation.它将x-forwarded-prefix标头添加到带有来自此注释的值的 http 请求。 You can use it, if your backend support such header.如果您的后端支持此类标头,则可以使用它。

For example, Spring Boot application can handle it by using property:例如,Spring Boot 应用程序可以通过使用属性来处理它:

server.forward-headers-strategy=framework

In your case ingress would look like the following:在您的情况下,入口将如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: my-ingress
 namespace: ingress-nginx
 annotations:
   kubernetes.io/ingress.class: nginx
   nginx.ingress.kubernetes.io/rewrite-target: /
   nginx.ingress.kubernetes.io/x-forwarded-prefix: /devops
spec:
 rules:
 - host: master1.dev.local
   http:
     paths:
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops

This solution has its downsides.此解决方案有其缺点。 It forces you to declare each service in separate ingress.它强制您在单独的入口中声明每个服务。

I met the similar issue recently.我最近遇到了类似的问题。

Assuming the "logs" hyperlink in your html uses a relative path, which means the hyperlink doesn't start with '/', then I think you can try to hit the page at http://hostname/devops/ instead of http://hostname/devops.假设您的 html 中的“日志”超链接使用相对路径,这意味着超链接不以“/”开头,那么我认为您可以尝试访问 http://hostname/devops/ 而不是 http 的页面: //主机名/devops。 (Note a / suffix in the first url.). (注意第一个 url 中的 / 后缀。)。

Then the "logs" hyperlink will be formed as http://hostname/devops/logs.然后“日志”超链接将形成为 http://hostname/devops/logs。

I think it's about how the browser identifies the 'base' url.我认为这与浏览器如何识别“基本”网址有关。 With accessing 'http://hostname/devops/, if there is no 'base' tag in the html header, the 'base' url will be figured out to be http://hostname/devops;访问'http://hostname/devops/,如果html头中没有'base'标签,'base' url将被认为是http://hostname/devops; while with 'http://hostname/devops', the base url will be http://hostname.使用“http://hostname/devops”时,基本 url 将是 http://hostname。

If it's not the case, there is discussion at https://github.com/kubernetes/ingress-nginx/issues/4149 .如果不是这种情况,在https://github.com/kubernetes/ingress-nginx/issues/4149有讨论。 It's suggested a workaround to use the nginx directive subs_filter with a configuration-snippet to make the href attributes relative and also add the base tag in the html header.建议使用带有配置片段的 nginx 指令 subs_filter 来使 href 属性相对并在 html 标头中添加基本标记的解决方法。

The ingress used is as below,使用的入口如下,

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: master1.dev.local
    http:
      paths:
      - backend:
          serviceName: devops1
          servicePort: 10311
        path: /devops(/|$)(.*)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM