Kubernetes Ingress 负载均衡器将所有内容重写到索引;为什么?

Kubernetes Ingress load balancer rewrites everything to index; why?

TL;DR 出于某种原因,每个 http 服务似乎都将路径重写为 /

我是 Kubernetes 的新手,正在尝试设置入口负载均衡器。

Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.6", GitCommit:"4bc5e7f9a6c25dc4c03d4d656f2cefd21540e28c", GitTreeState:"clean", BuildDate:"2017-09-14T06:55:55Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"7+", GitVersion:"v1.7.6-gke.1", GitCommit:"407dbfe965f3de06b332cc22d2eb1ca07fb4d3fb", GitTreeState:"clean", BuildDate:"2017-09-27T21:21:34Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

我正在 Google 容器引擎 (GKE)

中设置所有内容

它部分工作,这是一件好事。但是,出于某种原因,它将所有内容路由到我的服务,就好像请求是针对 /.

这里发生了什么?我的猜测是配置不佳。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ingress-main-ip"
spec:
  tls:
  - secretName: cert-main
    hosts:
    - api.example.com
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /my_service/*
        backend:
          serviceName: myService
          servicePort: main-port
      - path: /my_service2/*
        backend:
          serviceName: myService2
          servicePort: main-port

每当我向 api.example.com/my_service/ 发出请求时,myService 都会将该请求注册为来自索引——没问题。

https://api.example.com/my_service2/ 相同,它转到 myService2

但是每当我向 https://api.example.com/my_service/bogus/path/that/should/return/404 发出请求时,我的服务似乎都认为该请求正像以前一样再次指向 / 路径。

当然,当我在本地 运行 myService(恰好是 Go http 服务器)时,它工作得很好。 要特别清楚: 运行在本地 127.0.0.1/bogus/path/that/should/return/404 returns 预期的 404(以及当然其他 API 端点也可以)

这是一件非常奇怪的事情:每当我直接访问静态IP地址(又名ingress-main-ip,我们就说它是1.2.3.4),例如http://1.2.3.4/my_service/http://1.2.3.4/my_service2/总是 returns 来自 GKE 默认后端的 404,所以我的服务甚至没有被路由到。

总结:

  1. 为什么请求的域版本都路由到 /
  2. 为什么直接 IP 请求根本不起作用?

感谢您的宝贵时间和帮助!

我来回答第二个问题

非常奇怪的事情是由于 HTTP header "Host" 重要,因为你在 规则中指定了它 部分:

rules:
  - host: api.example.com           <----- THIS
    http:
      paths:
      - path: /my_service/*
        backend:
          serviceName: myService
          servicePort: main-port
      - path: /my_service2/*
        backend:
          serviceName: myService2
          servicePort: main-port

所以它用于将请求路由到适当的服务。如果你的service controller是nginx,那么"host:"就是它的server_name.

罗伯特对第二个问题的回答是正确的(非常感谢)

我刚刚弄清楚了主要问题,为什么我的所有路径似乎都被重写为 /

原来是将入口配置中指定的"path"路径发送到实际服务的服务器。 因此,例如,当尝试向 api.example.com/my_service/my_endpoint 发出 GET 请求时,我期望 my_service 只获取路径 /my_endpoint 但实际上它获取了完整的 /my_service/my_endpoint

在我看来,这似乎是一个非常糟糕的 kubernetes 副作用,路径应该是相对重写的。

无论如何,现在已经解决了。我 "thought" 将它们全部重写为 / 的原因是因为某些原因(我写入代码的逻辑错误)我的多路复用器正在捕获每个未知请求并将其发送到我的索引控制器。去图吧!