简体   繁体   中英

How should I configure Spring Cloud with Netflix Zuul and Eureka in a Docker contained in an EC2 instance

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM