spring-cloud-netflix: Cannot find a way to configure Eureka client with Docker swarm mode
When using Eureka client with Docker swarm mode, I didn’t find a way to correctly configure the client to notify the correct hostname / ip. With Docker swarm mode you have at least two networks (if the container exposes a port to the public network), the ingress and the overlay network used for internal cluster communication (the correct one to use for Eureka). The problem is that, in each container, you have two interfaces eth0 and eth1; these are assigned randomically to the ingress or overlay ip thus is not possible to benefit from spring.cloud.inetutils.ignoredInterfaces property. So what happens is that randomically Eureka clients advertise the correct host configuration. Did you have any similar case to this or is there a specific Eureka configuration that can help me with that?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 25 (6 by maintainers)
Commits related to this issue
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1820 — committed to diegochavezcarro/spmia4 by diegochavezcarro 7 years ago
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1820 — committed to diegochavezcarro/spmia4 by diegochavezcarro 7 years ago
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1820 — committed to diegochavezcarro/spmia4 by diegochavezcarro 7 years ago
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1820 — committed to diegochavezcarro/spmia4 by diegochavezcarro 7 years ago
- Adding docker setup and configuration to run services on docker containers — committed to pranav-patil/spring-microservices by pranav-patil 6 years ago
I have found two solutions to this problem:
spring.cloud.inetutils.preferredNetworkspropertyeureka.instance.hostName: service-nameandeureka.instance.preferIpAddress: false, where service-name is the same service-name specified in the Docker compose fileWhat do you think about them?
UPDATE4:
Day 2️⃣. I added code below in all my
spring-bootapps in a cluster.Lets check
configandregistryservices.Config:
Registry:
Overlay network
Remember, I asked about
10.0.0.2 / 10.0.0.2,10.0.0.4 / 10.0.0.4and so on which Eureka uses by default. Network interfaces show this one as Loopback. Actually every service in Docker Swarm has 3loobpackand 3ethinterfaces. When we set to prefer10.0addresses in yaml configuration, we force to use thisloopback, because the real eth hostname in hex format (979c83c891fa,b2c8b40d16de, etc).Okay, we got correct IP addresses on Eureka server from their clients. But we lost other configurations: urls, ports and so on. That’s why requests to gateway and other communications through Eureka stop working…
We need something like this:
But with new custom
EurekaClientConfigconfiguration we have:UPDATE5:
I override bean from autoconfiguration
org.springframework.cloud.netflix.eureka. EurekaClientAutoConfiguration#eurekaInstanceConfigBean()like this:And now I got next Eureka client registration:
And from container:
It is exactly what I want ☕️ I need to test docker swarm scaling with replicas and my problem looks solved.
UPDATE6:
Finish 🥇 I got this works. Docker swarm service replications and Eureka are friends now.
Even Hystrix Dashboard understands replicas count via
Feigncommucations:At this moment I think I solved my problem with Spring Cloud + Docker Swarm. If not, I let you know 😄
Hello everyone ✋ . Same problem with my spring-cloud (
Dalston.SR3) system in docker swarm.Option 2 (
preferIpAddress: false&service-name) really breaks the client-side load balancing (eureka + ribbon). That’s why I am trying to use option 1 (preferIpAddress: true&preferredNetworks).When we run a service in docker swarm, service without public ports registers in only overlay network (by default it’s
10.0.0.0/24, but we can create owndocker network createwith another mask, gateway, etc). When we register a service with public ports, docker swarm add this service to overlay (10.0.0.0/24or your own) and ingress (10.255.0.0/16) networks. Overlay lets services to communicate and ingress lets to swarm’s built-in load balancing between service replicas.This is my configuration
v1:With
v1configuration Eureka show this:Look at
instance-idin last column. By defaultinstance-idcreate by pattern:This means that
spring.cloud.client.hostnameis getting from ingress network while overlay is not ready.Eureka uses
instance-idto distinct between different instances of the same application. But if we checkhttp://localhost:8761/eureka/apps, everything is correct exceptinstance-id:I just change
instance-idpattern and create my configurationv2:And Eureka shows:
Okay. For now the most important feature is scaling. Lets try to run stack in docker swarm with 2
template-service-1and 3template-service-2:Look at IP addresses of all replicas of both services - they are equal 🤕
And the last test to check run-time scaling
docker service update --replicas 3 template-service-1&docker service update --replicas 1 template-service-2:Eureka understands that service’s replicas count are changing, but…
One more time. Look at
hostNameandipAddrof every instances of both services. They are equal 😣. Eureka has 3 instances of mytemplate-service-1with same ip10.0.0.8which was used on the 1th registration. Let’s check out our networkdocker network inspect stack_default:There are 3 replicas of
template-service-1:Why Eureka registered service’s replicas with same ip
10.0.0.12? 🤕 This IP address is not using anymore in overlay network, it was using for the 1th replica before I changed scale value. This means that Eureka remember 1th IP address of the 1th replica of any service and continue to use it for every other repicas.What do you think, guys? How can I fix that?
UPDATE1:
I just run the stack in docker swarm. I have gateway service with single replica. When it’s running first, it crashed because config server is not available yet. Then container restart again. It is okay in docker environment (restart=always and etc, u know 😄 ).
The most interesting thing is result IP address of gateway. First container got IP
10.0.0.10, but was terminated. Second container got IP10.0.0.11and was successfully run.Now lets look at Eureka and network state:
But this is from
docker network inspect stack_defaultAnd from container itself:
Eureka just registered gateway with IP of the 1th failed container. Is this DNS cache or what?
If I ping
gatewayfrom itself, IP is correct:But If I ping from another container, IP is wrong (cached with 1th failed container):
How can I solve this problem, if I understand it correctly? Can I force the Eureka clients to send their IP addresses itself without Eureka server’s DNS resolving from already invalid cache? Cheers ☕️
UPDATE2:
I found the way to specify hostname and ip for eureka clients:
From
/eureka/apps:Now I need to find the way to set these parameters with actual IP address of the container in my overlay network.
The code below doesn’t help, because
InetAddress.getLocalHost()get the externally advertised FQDN for the host (it’s cached in DNS too).Lets check all network interfaces:
And lets check actual
hostnameof service:But Eureka client is using 4th row with
10.0.0.2 10.0.0.2. What is that? IP address10.0.0.2of what? There is no anything with this IP addressdocker network inspect stack_default:UPDATE3:
I did the dirty trick:
System.getenv("HOSTNAME")returns exactly what I need:3f5ba074d5f7. And I just find the real IP address of this container. Lets look at Eureka:Looks like working thing 🔨 Next step is check the swarm scaling and client-side load balancing…
In think option 1 is more adequate. With option 2 load balancing is being made in docker swarm and not in the client, so we would not have client load balancing which is one of the key advantages of using Eureka plus Ribbon.
Does this issue need to be open anymore? Sounds like there is a solution using option 2 above