I am evaluating building microservices using Spring Boot and Spring Cloud (Zuul and Eureka) running in separate docker containers, deployed in separate Amazon EC2 instances.
I have a simple REST service that registers with Eureka, and have configured Zuul to route requests to this service by looking it up in Eureka.
I can get this to work running locally (ie not in Amazon/EC2) on my Mac using boot2docker, but when deployed on EC2, Zuul cannot find the service, and reports a 'Forwarding error' (status 500).
In EC2, everything is configured to run on port 80 (just while evaluating so I can easily access through our firewall). I can see both Zuul and my service in the Eureka system status page (although none of the links work!).
The clients are configured to find Eureka with a full AWS domain name, so I can see how they find Eureka OK. eg
client:
serviceUrl:
defaultZone: http://ec2-XX-XX-XX-XX.ap-southeast-2.compute.amazonaws.com:80/eureka/,http://ec2-YY-YY-YY-YY.ap-southeast-2.compute.amazonaws.com:80/eureka/
But, the clients seem to be registering themselves with their internal docker IP address (based on the Eureka system status links).
The edgeserver link points to http://172.17.0.2/info The trialservice link points to http://172.17.0.3/info
I'm guessing this is incorrect and that other EC2 instances don't know to get to this address.
I've read this page https://github.com/Netflix/eureka/wiki/Configuring-Eureka-in-AWS-Cloud which suggests using AWS EC2 Elastic IP addresses, but I was hoping I wouldn't have to do this.
I've also seen there is a current discussion around this subject here, https://github.com/spring-cloud/spring-cloud-netflix/issues/432
Has anyone managed to get this type of setup working, and if so, how did they configure the Eureka properties?
OK, to answer my own question, I've found a solution. It basically involves configuring eureka to use the hostname and docker to use the net=host option.
Here is my setup (just showing setup for one availability zone):
application.yml:
Zuul:
spring:
profiles: aws
server:
port: 80
eureka:
datacenter: cloud
instance:
preferIpAddress: false
client:
serviceUrl:
defaultZone: http://ec2-XX-XX-XX-XX.ap-southeast-2.compute.amazonaws.com:80/eureka/
Eureka:
spring:
profiles: aws-discoA
server:
port: 80
eureka:
instance:
preferIpAddress: false
datacenter: cloud
enableSelfPreservation: false
client:
name: eureka
preferSameZone: false
shouldOnDemandUpdateStatusChange: false
region: default
serviceUrl:
defaultZone: http://ec2-YY-YY-YY-YY.ap-southeast-2.compute.amazonaws.com:80/eureka/
Service:
spring:
profiles: aws
server:
port: 0 # or 80 if there is only 1 service/docker in this EC2
eureka:
datacenter: cloud
instance:
preferIpAddress: false
client:
serviceUrl:
defaultZone: http://ec2-XX-XX-XX-XX.ap-southeast-2.compute.amazonaws.com:80/eureka/
I'm not sure if "datacenter: cloud" is needed?
Then to launch each:
Zuul
sudo docker run -d --name edge -e JAVA_TOOL_OPTIONS="-Dspring.profiles.active=aws -Deureka.instance.hostname=$HOSTNAME" --net="host" edge
Eureka
sudo docker run -d --name discovery -e JAVA_TOOL_OPTIONS="-Dspring.profiles.active=aws-discoA -Deureka.instance.hostname=$HOSTNAME" --net="host" discovery
Service
sudo docker run -d --name service -e JAVA_TOOL_OPTIONS="-Dspring.profiles.active=aws -Deureka.instance.hostname=$HOSTNAME" --net="host" service
Just to ensure this works in a more complex setup, I configured more servers, some with multiple dockers per EC2 and now have the following setup.
This setup is duplicated in two availability zones with a load balancer in front of the Zuul servers. Each service has an endpoint that just returns its name, hostname, port and the number of times it has been called.
I can then hit the load balancer and see each service being called as the AWS load balancer and Ribbon load balancers cycle through the services.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.