【问题标题】:Kubernetes Ingress configuration rewrite problemKubernetes Ingress 配置重写问题
【发布时间】:2019-04-11 10:51:37
【问题描述】:

我正在创建一个配置以在 AWS 上的 Kubernetes 集群中托管一些应用程序。我有两个不同的应用程序,具有单独的服务/pod/选择器,但我想暂时用一个入口公开它们。

所以我创建了以下入口控制器

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /foo
        backend:
          serviceName: foo
          servicePort: 8080
      - path: /bar
        backend:
          serviceName: bar
          servicePort: 8080 

并且入口从 AWS 获取 ELB 没有任何问题,但是当我尝试浏览应用程序(使用 Tomcat 应用程序服务器的 Java 应用程序)时,我总是收到以下页面

这是经典的旧 Tomcat 欢迎页面,但每个请求总是返回 index.html(未加载 css/img),并且如果我尝试为应用程序使用正确的上下文路径,我会收到此页面。

如果我使用服务 (LoadBalancer) 公开应用程序,我可以在没有这些问题的情况下使用它,所以我认为入口配置有问题。

有什么想法吗?


更新

如果我使用像这样的单一路径的入口

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: foo
          servicePort: 8080

使用 INGRESSHOST url 我可以看到带有 img/css 的 Tomcat 主页,如果我浏览到 INGRESSHOST/APPCONTEXT,我可以毫无问题地使用该应用程序

【问题讨论】:

  • 检查您的浏览器网络日志,它尝试从哪个 url 获取资源。
  • 唯一正确的请求是主页,其他请求没有正确重写。 index.html img/css 未加载,因为它们使用相对路径
  • 服务在访问时会直接响应根路径吗?
  • 如果直接暴露,应用程序会回复其上下文路径。如果我删除入口并将服务发布为 LoadBalancer 一切正常。在入口配置中,如果我询问INGRESS_HOST/foo/foocontext,我总是会收到Tomcat 主页面(在INGRESS_HOST/foo 上可用)。对于以 foo 开头的每个请求,我都会收到 Tomcat 索引页
  • 第一件事:您在顶部共享的代码是入口资源而不是控制器。如果您也有共享控制器代码,也许会很好。我假设它是nginx deployment...?

标签: tomcat kubernetes kubernetes-ingress nginx-ingress amazon-eks


【解决方案1】:

如果您最近更改了 nginx-ingress 控制器的版本,那么原因可能是最近对其进行了更改。现在它使用正则表达式重写规则,也许您的重写目标总是被重写为“/”。我认为这些更改是在一月份的 0.22 版中引入的。

您的入口的新正确语法是:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
      - path: /foo(.*)
        backend:
          serviceName: foo
          servicePort: 8080
      - path: /bar(.*)
        backend:
          serviceName: bar
          servicePort: 8080 

【讨论】:

  • 好的,如果我使用这种语法,那么我现在可以看到加载了所有内容的 Tomcat 主页,所以 INGRESSHOST/foo/ 显示 Tomcat 主页,但是如果我尝试使用 INGRESSHOST/foo/myfooapp,它会重定向我到 INGRESSHOST/myfooapp,我从入口控制器收到 404 默认后端。
  • @FedericoPaparoni,重定向由您的应用程序完成。反向代理(这里的入口就像一个)的事情是请求的原始路径在到达接收应用程序时丢失。所以接收应用程序实际上认为请求的 URL 是 http://foo/myfooapp 并将用户重定向到以 /myfooapp 开头的绝对 URI,这显然是错误的。要在这样的设置中正确使用应用程序(带有重定向和绝对 URL 生成),应用程序应该有一个选项来设置其公共 URL。
  • @FedericoPaparoni 或者,如果您将加载在 tomcat 中的应用程序上下文挂载到与入口匹配的路径中,那么一切可能都会正常工作。您的应用程序应该可以在 kubernetes 集群中通过以下 URL 访问:http://foo/foo/myfooapphttp://bar/bar/myfooapp 在此设置中,您还可以删除重写目标注释。
  • 我理解这个问题,但不幸的是我不能对应用程序进行太多修改。使用主机(foo.example.com 和 bar.example.com),应用程序运行良好,并且粘性会话需要主机,所以我可以使用它。无论如何,感谢您对入口控制器的正则表达式更新的帮助
  • 将-path:/foo(.*)改成-path:/foo/(.*)后生效,在foo后面加了“/”
猜你喜欢
  • 2019-05-03
  • 1970-01-01
  • 2018-07-05
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
相关资源
最近更新 更多