[spring-projects/spring-boot]Istio Actor 管理端口不正确

2024-07-08 697 views
0

Spring Boot 2.3.7 Spring Cloud Hoxton SR8 Java 11

我们正在尝试 Istio 服务网格,但是当我们部署 Spring Boot 应用程序执行器端点时,它在 href 中返回错误的端口号或没有端口号。

我们已经management.server.port: 8081在 bootstrap.yaml 中进行了配置,因此我们可以通过此端口访问执行器。因此,当您访问时,http://10.0.0.1:8081/actuator/它自然会返回所有端点,但有一个问题,它不包含配置的端口号。当然,这种情况仅在存在 Istio 侧车容器时才会发生

{
  "_links": {
    "self": {
      "href": "http://10.0.0.1/actuator",
      "templated": false
    },
    "health-path": {
      "href": "http://10.0.0.1/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://10.0.0.1/actuator/health",
      "templated": false
    },
    "info": {
      "href": "http://10.0.0.1/actuator/info",
      "templated": false
    }
  }
}

回答

1

链接中的 href 来自传入请求的 URL。如果 Istio 正在代理请求,它应该使用属性设置 Boot 必须配置为使用的server.forward-headers-strategy转发标头。您能否检查您是否已按要求配置了应用程序?如果您认为您已经这样做了,请验证 Istio 在将请求转发到应用程序时是否添加了必要的标头。如果这些都无法解决问题,并且您希望我们花更多时间进行调查,我们将需要一个能够重现问题的最小样本才能做到这一点。

2

@wilkinsona 感谢您为我指明了方向,但从使用 web 到 webflux 的快速转变似乎解决了这个问题。这表明 servlet mvc 的特定内容导致了问题。

7

但问题是我们还不能将所有的 Web 服务迁移到 Webflux。

8

WebFlux 使用ForwardedHeaderTransformerX-Forwarded标头应用于请求 URL,但仅在server.forward-headers-strategy设置为时使用framework。Servlet 端有一个类似的类。还有使用嵌入式容器的内置标头处理的选项。如果设置为或您在被检测为云平台的环境中运行,X-Forwarded这将生效。server.forward-headers-strategynative

简而言之,从基于 Servlet 的 MVC 切换到 WebFlux 可能会改变遵守X-Forwarded标头的框架代码或遵守标头的容器代码。正如我上面所说,如果您希望我们花更多时间进行调查,我们将需要一个能够重现问题的最小样本才能做到这一点。

1

@wilkinsona 这是示例代码。https ://github.com/sabareeshkkanan/istio-debug,只需切换到 webflux 即可解决问题。此外,即使没有 webflux 也可以正常工作server.forward-headers-strategy: native

9

@sabareeshkkanan 能否用 readme 更新示例,描述如何使用 Istio 运行应用程序?应用程序本身只是等式的一半。

3

@philwebb @wilkinsona 我已经添加了文档,如果您还有其他问题,请告诉我

5

即使没有 webflux 也可以工作server.forward-headers-strategy: native

当部署到 K8S 时,这是可以预料到的,因为它会被检测为云平台,默认情况下启用前向标头的使用。

听起来,行为上的差异是由于 Tomcat 和 Netty 之间 X-Forwarded 标头处理方式不同造成的。希望我们可以使用您的示例来确认情况确实如此。

2

正如我所怀疑的,问题出在X-Forwarded-Envoy 添加的标头以及 Tomcat 如何处理它们。以下是 Tomcat 看到的请求标头示例:

host = 10.111.130.85:8081
user-agent = curl/7.64.1
accept = */*
x-forwarded-proto = http
x-request-id = e6373443-1668-4fcd-9bc1-7de20e6f4683
x-b3-traceid = df1a38ef71f0cec9b8ce2605691fb12f
x-b3-spanid = b8ce2605691fb12f
x-b3-sampled = 0
content-length = 0

根据主机标头的指示,请求已在端口 8081 上收到。Envoy 通过标x-forwarded-proto头指示这是一个 http 请求。在没有标头的情况下x-forwarded-port,TomcatRemoteIPValve假定转发请求的代理将使用端口 80,因此这是它在请求上配置的端口。有一个未解决的 Envoy 问题,用于添加端口标头,以告知 Tomcat 正在使用非标准 HTTP 端口。

相比之下,Reactor NettyDefaultHttpForwardedHeaderHandler仅在设置时才更改端口。这适合您的目的,但对于默认使用端口 80 和默认使用端口 443 的X-Forwarded-Proto代理不起作用。httphttps

在这个特定情况下,我认为该X-Forwarded-Proto标头弊大于利。如果没有附带的X-Forwarded-Port标头,它提供的信息可能会产生误导,而且考虑到所有操作都是通过 HTTP 完成的,这些信息没有任何价值。这意味着您可以通过设置以下方式禁用转发标头处理来避免此问题server.forward-headers-strategy: none

$ curl http://10.111.130.85:8081/actuator
{"_links":{"self":{"href":"http://10.111.130.85:8081/actuator","templated":false},"health":{"href":"http://10.111.130.85:8081/actuator/health","templated":false},"health-path":{"href":"http://10.111.130.85:8081/actuator/health/{*path}","templated":true},"info":{"href":"http://10.111.130.85:8081/actuator/info","templated":false}}}

我将关闭此问题,因为我们无法在 Spring Boot 中采取任何措施来改善这种情况。我建议订阅 Envoy 问题,以便您可以跟踪其进展。

8

如果有人遇到此问题,似乎只需使用 undertow 作为 web 服务器进行临时修复即可,直到 convoy 代理修复它。

4

感谢@sabareeshkkanan 分享您对 Undertow 的发现。UndertowProxyPeerAddressHandler与 Reactor Netty 类似,DefaultHttpForwardedHeaderHandler因为X-Forwarded-Proto标头对请求的端口没有影响。

你可以通过使用 undertow 作为 web 服务器来临时修复它

虽然更换容器可能很简单,只需要对 pom.xml 或 build.gradle 进行少量更改,但这可能会产生深远的影响。遇到此问题的其他任何人可能都希望考虑设置server.forward-headers-strategy: none一个更有针对性的解决方法,这样不会带来任何意外的副作用。

6

我同意@wilkinsona,但有一种情况我们不想禁用 server.forward-headers-strategy ,因为唯一的解决方案是迁移到 webflux 或 undertow。

6

@wilkinsona @sabareeshkkanan 一段时间以来,我一直被同样的问题困扰。不幸的是,完全禁用 Forward Headers 对server.forward-headers-strategy: none我们没有帮助,因为对于同一服务,我们还有一些需要代理主机和端口的情况,例如在反向代理后面运行服务。还有其他解决方案吗?例如强制 Istio 添加转发端口或其他什么?

7

这是我所做的。我为 spring / 控制器使用专用端口。因此,当 http 请求发送到特定服务 + 端口时,我会全面设置 x-forwarded-port 标头。

希望这可以帮助

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: app-actuator
  namespace: istio-system
spec:
  hosts:
  - "app.namespace.svc.cluster.local"
  http:
  - match:
    - port: 1234
    route:
    - destination:
        host: app.namespace.svc.cluster.local
        port:
          number: 1234
      headers:
        request:
          set:
            x-forwarded-port: "1234"