nginx入口子路径重定向

时间:2018-10-31 17:48:36

标签: nginx kubernetes kubernetes-ingress nginx-ingress

我有一个入口控制器和入口资源,所有/ devops都映射到后端的devopsservice中。当我尝试点击“ http://hostname/devops”时,一切正常,并且我得到一个页面(尽管没有CSS和样式),其中包含一组超链接,例如,其中一个是“日志”。

当我单击“日志”超链接时,它会将我重定向到http://hostname/logs,而我需要是http://hostname/devops/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"
spec:
 rules:
 - host: master1.dev.local
   http:
     paths:
     - backend:
         serviceName: devops1
         servicePort: 10311
       path: /devops

4 个答案:

答案 0 :(得分:0)

好像您的入口没有提供任何服务/devops/*。尝试添加另一个具有相同后端的路径/devops/*。基本上是这样:

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

在撰写本文时,在这一领域仍有一些work正在做。

答案 1 :(得分:0)

如果直接从浏览器访问http://hostname/devops/logs,那么肯定会得到想要的。但是,因为您单击了主页中的超链接,所以您只能获得http://hostname/logs,肯定会失败。

因此,您需要在入口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

答案 2 :(得分:0)

nginx.ingress.kubernetes.io/x-forwarded-prefix annotation可用于此目的。

它将x-forwarded-prefix头添加到带有该注释的值的http请求。如果您的后端支持此类标头,则可以使用它。

例如,Spring Boot应用程序可以通过使用属性来处理它:

server.forward-headers-strategy=framework

在您的情况下,入口看起来如下:

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

该解决方案有其缺点。它迫使您在单独的入口中声明每个服务。

答案 3 :(得分:0)

我最近遇到了类似的问题。

假设您的 html 中的“日志”超链接使用相对路径,这意味着超链接不是以“/”开头,那么我认为您可以尝试点击 http://hostname/devops/ 上的页面http://hostname/devops。 (注意第一个网址中的 / 后缀。)

然后“日志”超链接将形成为 http://hostname/devops/logs。

我认为这与浏览器如何识别“基本”网址有关。访问'http://hostname/devops/,如果html头中没有'base'标签,'base' url将被认为是http://hostname/devops;使用“http://hostname/devops”时,基本 url 将为 http://hostname。

如果不是这样,请在 https://github.com/kubernetes/ingress-nginx/issues/4149 进行讨论。建议使用带有配置片段的 nginx 指令 subs_filter 来使 href 属性相对并在 html 标头中添加 base 标记。

使用的入口如下,

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(/|$)(.*)