Search code examples
amazon-web-servicesdockercontainersamazon-route53amazon-ecs

Getting containers to talk to each other in Elastic Container Service (ECS)?


I'm using AWS and Elastic Container Service (ECS). I have 6 services, each running in their own container that need to talk to each other in order to work.

When I do a 'docker-compose' on my local machine, each service starts up in its own container and uses the default name that docker gives it as its hostname. I can access the database container using hostname 'database' from the 'registration-service' container, and so forth:

PORTS                    NAMES
0.0.0.0:8901->8901/tcp   common_authenticationservice_1
0.0.0.0:8888->8888/tcp   common_configserver_1
0.0.0.0:5555->5555/tcp   common_zuulserver_1
0.0.0.0:8761->8761/tcp   common_eurekaserver_1
0.0.0.0:8082->8082/tcp   common_registrationservice_1
0.0.0.0:5432->5432/tcp   common_database_1

When I deploy to ECS using 'ecs-cli compose' the services can't find each other anymore in the EC2 instance. The 'registration-service' looks for hostname 'database' and can't find it, as with the others:

PORTS                    NAMES
0.0.0.0:8888->8888/tcp   ecs-common-41-configserver-fa98a8edd6fabfd98f01
0.0.0.0:5432->5432/tcp   ecs-common-41-database-9e95dfb9d591e1d2f101
0.0.0.0:8901->8901/tcp   ecs-common-41-authenticationservice-92c4e6b7f5f49dcf0500
0.0.0.0:8082->8082/tcp   ecs-common-41-registrationservice-c4e384f7f39581a28901
0.0.0.0:8761->8761/tcp   ecs-common-41-eurekaserver-9eb6bc89ebf79ba50200
0.0.0.0:5555->5555/tcp   ecs-common-41-zuulserver-be8ff59cc0eee2965400

From what I understand, I need something that is aware of all of my containers, lets them register and checks their health. Ideally, this solution would give me a hostname that I can use for each service (and any identical services I want to scale out) and route DNS requests to one of these services.

I've tried creating a service on my ECS cluster with the 'service discovery' feature, but it asks to point to one of my containers and then complains that they are using the same port and refuses to start up. Perhaps this is not what I think it is?

Here is my docker-compose file for ECS:

version: "3"
services:
  eurekaserver:
     container_name: eurekaserver
     image:   294417223953.dkr.ecr.us-east-1.amazonaws.com/eureka-server:latest
     ports:
         - "8761:8761"

  configserver:
      image: 294417223953.dkr.ecr.us-east-1.amazonaws.com/configuration-server:latest
      ports:
         - "8888:8888"
      environment:
         EUREKASERVER_PORT: 8761
         EUREKASERVER_URI: "http://eurekaserver:8761/eureka/"
         ENCRYPT_KEY:       "IMSYMMETRIC"
  zuulserver:
      image: 294417223953.dkr.ecr.us-east-1.amazonaws.com/johncarnell/tmx-zuulsvr:chapter7
      ports:
        - "5555:5555"
      environment:
        PROFILE: "default"
        SERVER_PORT: "5555"
        CONFIGSERVER_PORT: 8888
        EUREKASERVER_PORT: 8761
        CONFIGSERVER_URI: "http://configserver:8888"
        EUREKASERVER_URI: "http://eurekaserver:8761/eureka/"
  database:
      image: postgres:9.5
      ports:
        - "5432:5432"
      environment:
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=******
        - POSTGRES_DB=practicejournal

  registrationservice:
      image: 294417223953.dkr.ecr.us-east-1.amazonaws.com/registration-service:latest
      ports:
        - "8082:8082"
      environment:
        PROFILE: "default"
        SERVER_PORT: "8082"
        ES_PORT:           9200
        DATABASE_PORT:     5432
        CONFIGSERVER_PORT: 8888
        EUREKASERVER_PORT: 8761
        AUTHSERVER_PORT:   8091
        CONFIGSERVER_URI: "http://configserver:8888"
        EUREKASERVER_URI: "http://eurekaserver:8761/eureka/"
        AUTHSERVER_URI:   "http://authenticationservice:8901/auth/user"
        ENCRYPT_KEY:       "IMSYMMETRIC"

  authenticationservice:
      image: 294417223953.dkr.ecr.us-east-1.amazonaws.com/authentication-service:latest
      ports:
        - "8901:8901"
      environment:
        PROFILE: "default"
        SERVER_PORT: "8901"
        DATABASE_PORT:     5432
        CONFIGSERVER_PORT: 8888
        EUREKASERVER_PORT: 8761
        CONFIGSERVER_URI: "http://configserver:8888"
        EUREKASERVER_URI: "http://eurekaserver:8761/eureka/"
        ENCRYPT_KEY:       "IMSYMMETRIC"

Also, I have a script that runs on the docker container just after it is started. Eventually, this script starts the Java microservice:

#!/bin/sh

echo "********************************************************"
echo "Waiting for the eureka server to start on port $EUREKASERVER_PORT"
echo "********************************************************"
while ! `nc -z eurekaserver  $EUREKASERVER_PORT`; do sleep 3; done
echo "******* Eureka Server has started"

echo "********************************************************"
echo "Waiting for the database server to start on port $DATABASE_PORT"
echo "********************************************************"
while ! `nc -z database $DATABASE_PORT`; do sleep 3; done
echo "******** Database Server has started "

echo "********************************************************"
echo "Waiting for the configuration server to start on port $CONFIGSERVER_PORT"
echo "********************************************************"
while ! `nc -z configserver $CONFIGSERVER_PORT`; do sleep 3; done
echo "*******  Configuration Server has started"

echo "********************************************************"
echo "Starting Organization Service                           "
echo "********************************************************"
java -Djava.security.egd=file:/dev/./urandom -Dserver.port=$SERVER_PORT   \
     -Deureka.client.serviceUrl.defaultZone=$EUREKASERVER_URI             \
     -Dspring.cloud.config.uri=$CONFIGSERVER_URI                          \
     -Dspring.profiles.active=$PROFILE                                   \
     -Dsecurity.oauth2.resource.userInfoUri=$AUTHSERVER_URI               \
     -jar /usr/local/registrationservice/@[email protected]

This can't be a unique problem. Am I missing something? What AWS solution will help me register containers in ECS, route requests between them and check their health and how do I set this up?


Solution

  • 1: I see that to connect from container A to container B There should be a name for the containers. 2: Container B which depends on container A should have Link of Container A. 3: In your case, the Container Configserver depends on the Eurekaserver. So there should be a link of Eurekaserver in the Configserver. 4: There should be Unique Container Name specified So that others containers can talk to them using that. 5: I have updated the docker-compose file, Do have check with it and let me know If there are any concerns.

    version: '3'
    services:
        eurekaserver:
            container_name: eurekaserver
            image: '294417223953.dkr.ecr.us-east-1.amazonaws.com/eureka-server:latest'
            ports:
                - '8761:8761'
        configserver:
            container_name: configserver
            image: '294417223953.dkr.ecr.us-east-1.amazonaws.com/configuration-server:latest'
            ports:
                - '8888:8888'
            environment:
                EUREKASERVER_PORT: 8761
                EUREKASERVER_URI: 'http://eurekaserver:8761/eureka/'
                ENCRYPT_KEY: IMSYMMETRIC
            links:
                - eurekaserver
        zuulserver:
            container_name: zuulserver
            image: '294417223953.dkr.ecr.us-east-1.amazonaws.com/johncarnell/tmx-zuulsvr:chapter7'
            ports:
                - '5555:5555'
            environment:
                PROFILE: default
                SERVER_PORT: '5555'
                CONFIGSERVER_PORT: 8888
                EUREKASERVER_PORT: 8761
                CONFIGSERVER_URI: 'http://configserver:8888'
                EUREKASERVER_URI: 'http://eurekaserver:8761/eureka/'
            links:
                - eurekaserver
                - configserver
        database:
            container_name: database
            image: 'postgres:9.5'
            ports:
                - '5432:5432'
            environment:
                - POSTGRES_USER=postgres
                - 'POSTGRES_PASSWORD=******'
                - POSTGRES_DB=practicejournal
        authenticationservice:
            container_name: authenticationservice
            image: '294417223953.dkr.ecr.us-east-1.amazonaws.com/authentication-service:latest'
            ports:
                - '8901:8901'
            environment:
                PROFILE: default
                SERVER_PORT: '8901'
                DATABASE_PORT: 5432
                CONFIGSERVER_PORT: 8888
                EUREKASERVER_PORT: 8761
                CONFIGSERVER_URI: 'http://configserver:8888'
                EUREKASERVER_URI: 'http://eurekaserver:8761/eureka/'
                ENCRYPT_KEY: IMSYMMETRIC
            links:
                - eurekaserver
                - configserver
        registrationservice:
            container_name: registrationservice
            image: '294417223953.dkr.ecr.us-east-1.amazonaws.com/registration-service:latest'
            ports:
                - '8082:8082'
            environment:
                PROFILE: default
                SERVER_PORT: '8082'
                ES_PORT: 9200
                DATABASE_PORT: 5432
                CONFIGSERVER_PORT: 8888
                EUREKASERVER_PORT: 8761
                AUTHSERVER_PORT: 8091
                CONFIGSERVER_URI: 'http://configserver:8888'
                EUREKASERVER_URI: 'http://eurekaserver:8761/eureka/'
                AUTHSERVER_URI: 'http://authenticationservice:8901/auth/user'
                ENCRYPT_KEY: IMSYMMETRIC
            links:
                - eurekaserver
                - configserver
                - authenticationservice
    

    It is better to add the HealthCheck and the Depends-On Key value Pairs for the Containers. Check Link Here for details.