简体   繁体   English

Spring启动,获取Docker暴露端口进行eureka注册

[英]Spring boot, get Docker exposed port for eureka registration

I have a simple Eureka server that is pretty much the source from: https://spring.io/guides/gs/service-registration-and-discovery/ 我有一个简单的Eureka服务器,它几乎来自: https//spring.io/guides/gs/service-registration-and-discovery/

I have the spring client successfully registering with eureka, and also was able to get the docker image of the client, to register with eureka as well. 我让spring客户端成功注册了eureka,并且能够获得客户端的docker镜像,也可以在eureka注册。 However, what I want to do is be able to assign docker random port (ephemeral port range) by doing: 但是,我想要做的是能够通过执行以下操作来分配docker随机端口(临时端口范围):

docker run -p 8080 MY_IMAGE

I see that I can go to the resful app (eureka client) via the ephemeral port docker assigns...however, in Eureka registration, the port assigned is 8080, due to the spring configs. 我看到我可以通过短暂的端口码头分配给强大的应用程序(eureka客户端)...但是,在Eureka注册中,由于弹簧配置,分配的端口是8080。

application.yaml: application.yaml:

server:
  port: 8080

I know I can create a custom eureka config to overwrite the default by doing something like this: 我知道我可以通过执行以下操作来创建自定义eureka配置来覆盖默认值:

 @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfig() {
        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
        config.setPreferIpAddress(true);
        config.setNonSecurePort(8085); //or any port i want
        return config;
    }

but my question is....how can i get the docker exposed port (ephemeral port) in my app so that i can pass it on to eureka? 但我的问题是......我怎么能在我的应用程序中获得docker暴露端口(临时端口),以便我可以将它传递给eureka?

I successfully assigned random port for my eureka clients as below example. 我成功为我的eureka客户端分配了随机端口,如下例所示。

My microservice client docker file content is, 我的微服务客户端docker文件内容是,

   FROM openjdk:8-jdk-alpine
LABEL maintainer="tharanga.w@archisoftglobal.com"
VOLUME /tmp
ENV SERVER_PORT 0
EXPOSE ${SERVER_PORT}
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar", "$@"]

docker run command is, docker run命令是,

sudo docker run  -e spring.profiles.active="dev"  -e SERVER_PORT=0 --name archisoft-common-usermanger archisoft-common-usermanger

I'm currently working on the same issue. 我目前正在研究同样的问题。 My case is little bit more difficult, because I am going to use -- scale option to run as many running containers as I need, but it is still relevant to your question. 我的情况稍微有些困难,因为我将使用 - scale选项来运行我需要的运行容器,但它仍然与您的问题相关。 After day long research I found that the best way to obtain ephemeral port is to call native docker API and ask docker for real port number. 经过一天的研究,我发现获得短暂端口的最佳方法是调用本地docker API并向docker请求真正的端口号。 My code is: 我的代码是:

@Value("${docker.uri.template}")
private String dockerUriTemplate;
@Value("${docker.protocol}")
String dockerProtocol;
@Value("${docker.host}")
String dockerHost;
@Value("${docker.port}")
String dockerPort;
@Value("${server.port}")
String springServerPort;
// -------
@Bean
@Autowired
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) {
    Integer hostPort = 0;

    String containerHostName = getHostname();
    String dockerUri = String.format(dockerUriTemplate, dockerProtocol, dockerHost, dockerPort, containerHostName);

    DockerNetworkSettings networkSettings = new RestTemplate().getForObject(
            dockerUri, DockerNetworkSettings.class);
    hostPort = Integer.parseInt(networkSettings.getNetworkSettings().getPorts().get(springServerPort.concat("/tcp")).get(0).get("HostPort"));

    EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
    config.setNonSecurePort(hostPort);
    config.setHostname(dockerHost);
    config.getMetadataMap().put("instanceId", getHostname());
    return config;
}

DockerNetworkSettings class: DockerNetworkSettings类:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Proudly created by dmaslov on 01/02/2018.
*/

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect
public class DockerNetworkSettings implements Serializable {
private long id;
@JsonProperty("NetworkSettings")
private NetworkSettings NetworkSettings;

public DockerNetworkSettings.NetworkSettings getNetworkSettings() {
    return NetworkSettings;
}

public void setNetworkSettings(DockerNetworkSettings.NetworkSettings networkSettings) {
    NetworkSettings = networkSettings;
}

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect
public class NetworkSettings {
    @JsonProperty("Ports")
    private LinkedHashMap<String, ArrayList<LinkedHashMap<String,String>>> ports;

    public LinkedHashMap<String, ArrayList<LinkedHashMap<String,String>>> getPorts() {
        return ports;
    }

    public void setPorts(LinkedHashMap ports) {
        this.ports = ports;
    }
}
}

Application settings are: 应用程序设置为:

docker:
 uri:
  template: "%s://%s:%s/containers/%s/json"
 protocol: http
 host: docker8978
 port: 2376

I hope it will help somebody 我希望它会对某人有所帮助

You could pass the port as an enviroment property: 您可以将端口作为环境属性传递:

docker run -p 8085:8085 MY_IMAGE -e EUREKA_PORT=8085

Then in your application.yml 然后在你的application.yml中

eureka:
  instance:
     hostname: ${APPLICATION_DOMAIN}
     nonSecurePort: ${EUREKA_PORT:8780}

This will cause your app to look for the environment varible that is passed to the container or use the fallback port. 这将导致您的应用程序查找传递给容器的环境变量或使用回退端口。

Of course you can also inject the value from the application.yml with @Value into you bean to set the port. 当然,您也可以将带有@Value的application.yml中的值注入到bean中以设置端口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Boot Eureka微服务发现和注册在Docker中失败 - spring boot Eureka microservice discovery and registration fails in docker Spring Boot注册服务器(Eureka服务器) - Spring Boot Registration Server(Eureka Server) 使用 Spring Boot 的 Docker 和 Eureka 无法注册客户端 - Docker and Eureka with Spring Boot failing to register clients 无法连接到公开的Docker端口 - Cannot connect to exposed Docker port 如何在一个 Spring Boot 应用程序中的不同端口上运行 api-gateway(Netflix Zuul) 和 Eureka Server - How to run api-gateway(Netflix Zuul) and Eureka Server on different port in one Spring Boot application 是否有任何 Spring 引导微服务注册来获取有关我所有服务的信息,它们有哪些端口、名称、启动/关闭? - Is there any Spring Boot Microservice Registration to get information about all my services, which port they have, names, up/down? 如何让 Javamelody 使用不同的端口(Spring Boot+暴露的两个 HTTP 端口) - How to make Javamelody use different port (Spring Boot+two HTTP ports exposed) 具有Eureka依赖关系的Spring Boot无法启动 - Spring boot with Eureka Dependency fails to boot 带有 Eureka DiscoveryClient 的 Spring Boot 应用程序无法启动 - Spring Boot app with Eureka DiscoveryClient fails to start 没有 Spring-boot 的 Eureka 服务发现 - Eureka service discovery without Spring-boot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM