尽管有 docker 个容器的随机外部端口,但仍使用 Eureka
Use Eureka despite having random external port of docker containers
我正在编写一个应用程序,它由几个 spring 基于引导的微服务组成,前端有一个基于 zuul 的反向代理 -
当我在我的机器上启动服务时它可以工作,但是对于服务器推出我想使用 docker 来提供服务,但这现在似乎不可能。
通常您会在容器外部有一个固定的 "internal" 端口和随机端口。但是容器中的应用不知道外部端口(和 IP)。
Netflix 工具符合我想要编写高效微服务架构的要求,并且在概念上我真的很喜欢 docker。
据我所知,启动容器,收集主机上的外部端口并将其传递给应用程序会非常麻烦,因为您不能在应用程序启动后简单地更改端口。
有什么方法可以将 eureka 与基于 docker 的客户端一起使用吗?
[更新]
我想我没有很好地解释这个问题。所以也许这更能说明问题:
eureka server本身可以运行 in docker,因为我只有一个,外部端口无所谓。我可以使用 link 功能从客户端访问它。
问题出在客户端注册的URL。
例如 https://localhost:8080/ but due to dynamic port assignment it is really only accessible via https://localhost:54321/
所以 eureka 会 return 错误 URL 服务。
更新
我已经在下面更新了我的答案,所以看看那里。
我自己找到了一个解决方案,这可能不是最好的解决方案,但它适合我...
当您使用“--net=host”(主机网络)启动 docker 时,您将直接使用主机网络堆栈。然后我只使用 0 作为 spring-boot 的端口,spring 为我随机化端口,因为它使用主机网络堆栈,所以没有转换到不同的端口(和 IP)。
虽然有一些缺点:
- 当您使用主机网络时,您不能将这些容器的 link 功能用作 link 源或目标。
- 使用 hosts 网络堆栈会导致实例封装较少,这可能是一个问题,具体取决于您的项目。
希望对你有帮助
很多时间过去了,我想我应该进一步详细说明:
如果您使用 docker 来托管您的 spring 应用程序,请不要使用随机端口!使用固定端口,因为每个容器都有自己的 IP,因此每个服务都可以使用相同的端口。这让生活变得更轻松。
如果您有面向 public 的服务,那么无论如何您都会使用固定端口。
对于通过 maven 或例如命令行的本地启动,有一个使用随机端口的专用配置文件,因此您不会有冲突(但请注意周围存在或已经存在一些错误随机端口和服务注册)
如果出于任何原因你想要或需要使用主机网络,你当然可以使用随机端口,但大多数时候你不应该!
您可以为每个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。
我正在编写一个应用程序,它由几个 spring 基于引导的微服务组成,前端有一个基于 zuul 的反向代理 -
当我在我的机器上启动服务时它可以工作,但是对于服务器推出我想使用 docker 来提供服务,但这现在似乎不可能。
通常您会在容器外部有一个固定的 "internal" 端口和随机端口。但是容器中的应用不知道外部端口(和 IP)。
Netflix 工具符合我想要编写高效微服务架构的要求,并且在概念上我真的很喜欢 docker。 据我所知,启动容器,收集主机上的外部端口并将其传递给应用程序会非常麻烦,因为您不能在应用程序启动后简单地更改端口。
有什么方法可以将 eureka 与基于 docker 的客户端一起使用吗?
[更新] 我想我没有很好地解释这个问题。所以也许这更能说明问题:
eureka server本身可以运行 in docker,因为我只有一个,外部端口无所谓。我可以使用 link 功能从客户端访问它。
问题出在客户端注册的URL。 例如 https://localhost:8080/ but due to dynamic port assignment it is really only accessible via https://localhost:54321/
所以 eureka 会 return 错误 URL 服务。
更新 我已经在下面更新了我的答案,所以看看那里。
我自己找到了一个解决方案,这可能不是最好的解决方案,但它适合我...
当您使用“--net=host”(主机网络)启动 docker 时,您将直接使用主机网络堆栈。然后我只使用 0 作为 spring-boot 的端口,spring 为我随机化端口,因为它使用主机网络堆栈,所以没有转换到不同的端口(和 IP)。
虽然有一些缺点:
- 当您使用主机网络时,您不能将这些容器的 link 功能用作 link 源或目标。
- 使用 hosts 网络堆栈会导致实例封装较少,这可能是一个问题,具体取决于您的项目。
希望对你有帮助
很多时间过去了,我想我应该进一步详细说明:
如果您使用 docker 来托管您的 spring 应用程序,请不要使用随机端口!使用固定端口,因为每个容器都有自己的 IP,因此每个服务都可以使用相同的端口。这让生活变得更轻松。
如果您有面向 public 的服务,那么无论如何您都会使用固定端口。
对于通过 maven 或例如命令行的本地启动,有一个使用随机端口的专用配置文件,因此您不会有冲突(但请注意周围存在或已经存在一些错误随机端口和服务注册)
如果出于任何原因你想要或需要使用主机网络,你当然可以使用随机端口,但大多数时候你不应该!
您可以为每个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。