微服务在 Eureka 上注册 Docker 个内部 IP,而不是 public 个
Microservices registering Docker internal IP on Eureka instead of public one
我正在尝试在 Eureka 上注册一些微服务。它们部署在远程机器上,我希望能够在 Eureka 上看到机器的 IP,但我只能看到像 172.17.0.8
这样的私有 IP,无法从外部访问。
因为这些微服务是 运行 在 Docker 容器上,我明白我需要告诉服务获取主机的 IP 而不是 Docker 的,但我真的不知道看看如何。
我在 github -> https://github.com/spring-cloud/spring-cloud-netflix/issues/432
上看到了这个问题
并尝试过:
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=
不太行。有没有不涉及向我的服务添加代码或使用 AWS 的 API 的方法?
解决方案是使用一个小脚本在 Docker 容器中注入 public IP:
entrypoint.sh
export DOCKER_HOST_IP=$(curl --retry 3 --connect-timeout 2 --max-time 2 -s 169.254.169.254/latest/meta-data/public-ipv4)
echo $DOCKER_HOST_IP > /var/log/dockerIp.log
exec "$@"
然后将Docker文件修改为运行开头:
FROM java:8
VOLUME /tmp
EXPOSE 9000
ADD service-1.0-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
CMD bash -c 'source /usr/local/bin/entrypoint.sh && java -Djava.security.egd=file:/dev/./urandom -jar /app.jar'
主要问题是从脚本中导出变量,因为我们使用的 source
仅在 bash
中可用,这就是 CMD 的原因。
这个脚本可以手动放置在项目中,尽管我们在我们的 maven 构建中将它配置为自动资源下载:
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://url/entrypoint.sh</url>
<outputDirectory>${project.build.directory}/docker</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
我在我的环境中遇到了同样的问题 - 它是在 eureka 上注册容器 ID 而不是主机名。但这不在 AWS 上,因此无法为 public ip 调用 API。下面的命令解决了我的问题-
sudo docker run -i --net=host <dockerregistry_host>/<appName>:tag
我正在尝试在 Eureka 上注册一些微服务。它们部署在远程机器上,我希望能够在 Eureka 上看到机器的 IP,但我只能看到像 172.17.0.8
这样的私有 IP,无法从外部访问。
因为这些微服务是 运行 在 Docker 容器上,我明白我需要告诉服务获取主机的 IP 而不是 Docker 的,但我真的不知道看看如何。
我在 github -> https://github.com/spring-cloud/spring-cloud-netflix/issues/432
上看到了这个问题并尝试过:
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=
不太行。有没有不涉及向我的服务添加代码或使用 AWS 的 API 的方法?
解决方案是使用一个小脚本在 Docker 容器中注入 public IP:
entrypoint.sh
export DOCKER_HOST_IP=$(curl --retry 3 --connect-timeout 2 --max-time 2 -s 169.254.169.254/latest/meta-data/public-ipv4)
echo $DOCKER_HOST_IP > /var/log/dockerIp.log
exec "$@"
然后将Docker文件修改为运行开头:
FROM java:8
VOLUME /tmp
EXPOSE 9000
ADD service-1.0-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
CMD bash -c 'source /usr/local/bin/entrypoint.sh && java -Djava.security.egd=file:/dev/./urandom -jar /app.jar'
主要问题是从脚本中导出变量,因为我们使用的 source
仅在 bash
中可用,这就是 CMD 的原因。
这个脚本可以手动放置在项目中,尽管我们在我们的 maven 构建中将它配置为自动资源下载:
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://url/entrypoint.sh</url>
<outputDirectory>${project.build.directory}/docker</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
我在我的环境中遇到了同样的问题 - 它是在 eureka 上注册容器 ID 而不是主机名。但这不在 AWS 上,因此无法为 public ip 调用 API。下面的命令解决了我的问题-
sudo docker run -i --net=host <dockerregistry_host>/<appName>:tag