19

我正在编写一个应用程序,它由几个基于 Spring Boot 的微服务组成,前端有一个基于 zuul 的反向代理 -

当我在我的机器上启动服务时它可以工作,但是对于服务器部署,我想使用 docker 来提供服务,但这似乎现在不可能。

通常你会在容器外部有一个固定的“内部”端口和随机端口。但是容器中的应用程序不知道外部端口(和 IP)。

Netflix 工具与我想要编写高效的微服务架构相匹配,并且在概念上我真的很喜欢 docker。据我所知,启动容器会很麻烦,收集主机上的外部端口并将其传递给应用程序,因为您不能在应用程序启动后简单地更改端口。

有什么方法可以将 eureka 与基于 docker 的客户端一起使用?

[更新] 我想我在解释问题方面做得很差。所以也许这更澄清了一点:

eureka 服务器本身可以在 docker 中运行,因为我只有一个,外部端口无所谓。我可以使用链接功能从客户端访问它。

问题是客户端注册自己的 URL。例如https://localhost:8080/但由于动态端口分配,它实际上只能通过https://localhost:54321/访问

所以 eureka 会为服务返回错误的 URL。

更新 我在下面更新了我的答案,所以看看那里。

4

2 回答 2

7

我自己找到了一个解决方案,这可能不是最好的解决方案,但它适合我......

当您使用“--net=host”(主机网络)启动 docker 时,您可以直接使用主机网络堆栈。然后我只使用 0 作为 spring-boot 的端口,spring 为我随机化了端口,因为它使用主机网络堆栈,所以没有转换到不同的端口(和 IP)。

不过也有一些缺点:

  • 当您使用主机网络时,您不能将这些容器的链接功能用作链接源或目标。
  • 使用 hosts 网络堆栈会导致对实例的封装较少,这可能是一个问题,具体取决于您的项目。

我希望它有帮助

很多时间过去了,我想我应该进一步详细说明:

  1. 如果您使用 docker 托管您的 spring 应用程序,请不要使用随机端口!使用固定端口,因为每个容器都有自己的 IP,因此每个服务都可以使用相同的端口。这让生活变得轻松了很多。

  2. 如果您有面向公众的服务,那么无论如何您都会使用固定端口。

  3. 对于通过 maven 或例如命令行的本地启动,有一个使用随机端口的专用配置文件,因此您不会有冲突(但请注意,随机端口和服务注册存在或已经存在一些错误)

  4. 如果出于某种原因您想要或需要使用主机网络,您当然可以使用随机端口,但大多数时候您不应该!

于 2015-05-08T05:26:08.140 回答
4

您可以为每个 docker 实例设置一个目录并在主机和实例之间共享它,然后将端口和 IP 地址写入该目录中的文件。

$ instanceName=$(generate random instance name)
$ dirName=/var/lib/docker/metadata/$instanceName
$ mkdir -p $dirName
$ docker run -name $instanceName -v ${dirName}:/mnt/metadata ...
$ echo $(get port number and host IP) > ${dirName}/external-address

然后,您只需从应用程序中读取/mnt/metadata/external-address并将该信息与 Eureka 一起使用。

于 2015-05-08T05:45:25.007 回答