nginx 入口子路径重定向
nginx ingress sub path redirection
我有一个入口控制器和入口资源 运行 所有 /devops 都映射到后端的 devopsservice。当我尝试点击“http://hostname/devops”时,一切正常,我得到一个带有一组超链接的页面(尽管没有 CSS 和样式),例如其中一个是 "logs".
当我点击 "logs" 超链接时,它会将我重定向到 http://hostname/logs whereas I need it to be 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
看起来您的入口没有提供任何服务 /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
更新:以上 deprecated 赞成这样的事情:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
如果您直接从浏览器访问 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
nginx.ingress.kubernetes.io/x-forwarded-prefix
annotation 可用于此目的。
它使用此注释中的值将 x-forwarded-prefix
header 添加到 http 请求。你可以使用它,如果你的后端支持 header.
例如,Spring启动应用程序可以使用属性处理它:
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
此解决方案有其缺点。它迫使您在单独的入口中声明每个服务。
我最近遇到了类似的问题。
假设您 html 中的“日志”超链接使用相对路径,这意味着超链接不是以“/”开头,那么我认为您可以尝试访问 http:/ /hostname/devops/ 而不是 http:///hostname/devops。 (注意第一个url中的/后缀)。
然后“日志”超链接将形成为 http:///hostname/devops/logs。
我认为是关于浏览器如何识别'base' url。访问'http://hostname/devops/,如果htmlheader中没有'base'标签,就会计算出'base'url输出为 http:///hostname/devops;而使用 'http://hostname/devops',基础 url 将是 http://hostname.
如果不是这样,请在 https://github.com/kubernetes/ingress-nginx/issues/4149 进行讨论。建议使用带有 configuration-snippet 的 nginx 指令 subs_filter 来使 href 属性相对,并在 html header.[=12= 中添加基本标记。 ]
使用的ingress如下,
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
我有一个入口控制器和入口资源 运行 所有 /devops 都映射到后端的 devopsservice。当我尝试点击“http://hostname/devops”时,一切正常,我得到一个带有一组超链接的页面(尽管没有 CSS 和样式),例如其中一个是 "logs".
当我点击 "logs" 超链接时,它会将我重定向到 http://hostname/logs whereas I need it to be 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
看起来您的入口没有提供任何服务 /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
更新:以上 deprecated 赞成这样的事情:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
如果您直接从浏览器访问 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
nginx.ingress.kubernetes.io/x-forwarded-prefix
annotation 可用于此目的。
它使用此注释中的值将 x-forwarded-prefix
header 添加到 http 请求。你可以使用它,如果你的后端支持 header.
例如,Spring启动应用程序可以使用属性处理它:
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
此解决方案有其缺点。它迫使您在单独的入口中声明每个服务。
我最近遇到了类似的问题。
假设您 html 中的“日志”超链接使用相对路径,这意味着超链接不是以“/”开头,那么我认为您可以尝试访问 http:/ /hostname/devops/ 而不是 http:///hostname/devops。 (注意第一个url中的/后缀)。
然后“日志”超链接将形成为 http:///hostname/devops/logs。
我认为是关于浏览器如何识别'base' url。访问'http://hostname/devops/,如果htmlheader中没有'base'标签,就会计算出'base'url输出为 http:///hostname/devops;而使用 'http://hostname/devops',基础 url 将是 http://hostname.
如果不是这样,请在 https://github.com/kubernetes/ingress-nginx/issues/4149 进行讨论。建议使用带有 configuration-snippet 的 nginx 指令 subs_filter 来使 href 属性相对,并在 html header.[=12= 中添加基本标记。 ]
使用的ingress如下,
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)