Spring Cloud Skipper shell - 没有合适的 HttpMessageConverter

Spring Cloud Skipper shell - no suitable HttpMessageConverter

我是 运行 Spring NGINX 代理背后的 Cloud Skipper。当我尝试在使用代理 url、

的笔记本电脑上使用本地 shell 运行 连接到 Skipper 服务器时
I get the error: Could not extract response: no suitable HttpMessageConverter found for response type [org.springframework.hateoas.Resources<org.springframework.cloud.skipper.domain.Deployer>] and content type [text/html]
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.

我试过 Skipper NGINX 代理 url 之类的。 https://example.com/skipper/api/about and https://example.com/skipper/api/deployers 在浏览器和浏览器开发者工具上显示响应 header 是 content-type: application/hal+json;charset=UTF-8

运行 船长直接在船长服务器所在的主机上 运行 localhost url 工作正常。只有通过 NGINX 代理 url 访问时才会出错。

Could not extract response: no suitable HttpMessageConverter found for response type [org.springframework.hateoas.Resources<org.springframework.cloud.skipper.domain.Deployer>] and content type [text/html]
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [org.springframework.hateoas.Resources<org.springframework.cloud.skipper.domain.Deployer>] and content type [text/html]
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:121)
        at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:995)
        at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:978)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:710)
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:628)
        at org.springframework.hateoas.client.Traverson$TraversalBuilder.toObject(Traverson.java:344)
        at org.springframework.cloud.skipper.client.DefaultSkipperClient.listDeployers(DefaultSkipperClient.java:335)
        at org.springframework.cloud.skipper.shell.command.PlatformCommands.list(PlatformCommands.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:246)
        at org.springframework.shell.Shell.evaluate(Shell.java:180)
        at org.springframework.shell.Shell.run(Shell.java:142)
        at org.springframework.shell.jline.InteractiveShellApplicationRunner.run(InteractiveShellApplicationRunner.java:84)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:794)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
        at org.springframework.cloud.skipper.shell.ShellApplication.main(ShellApplication.java:32)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) 

此问题的根本原因:TLS 在代理处终止,Spring Cloud Skipper 在 Nginx 代理后面的 "http" 端口上 运行。因此,spring cloud skipper hateoas 生成 "http" 个链接而不是 "https"。当 shell 尝试在 Spring Cloud Skipper hateoas 返回的 URLS (http) 上 "GET" 时,Proxy 请求重定向到带有 308 的 https,这导致了异常。

我暂时关闭了带有注释 "nginx.ingress.kubernetes.io/ssl-redirect: false" 的 Kubernetes Nginx 入口资源级别的重定向。

稍后我会 post 更多详细信息,当我弄清楚如何配置代理 headers 以在 Spring Cloud Skipper 中生成 "https" url 而不是 http 时。

或者另一种解决方案可以是在 Proxy 中配置 TLS 直通,并通过在 Skipper 中启用 TLS 来终止 Skipper 中的 TLS。

设置以下 属性 application.yml 解决了问题。

      server:
        use-forward-headers: true