Error while trying for a container-to-container communication with swarm mode in multihost networking

I performed the following steps

Step 1: Created swarm cluster with two linux servers. Node1 acts as manager and Node2 acts as worker.

Step 2: Created an overlay network and attach containers to the network.

docker network create -d overlay int

Step 3: Created a service user which can be accessed from the browser

docker service create --network int --name user -p 7799:8080 user bash

Step 4: Created a service say-hello which can be accessed by the user service

docker service create --network int --name say-hello say-hello bash

Step 5. Access http://:7799/hi, the user service try to access say-hello service which should return a simple value. I am getting the below error

[Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for “http://say-hello/greeting”: Connection refused (Connection refused); nested exception is Connection refused (Connection refused)] with root cause Connection refused (Connection refused)

Step 6. I pinged user and say-hello container with their container ids. Request is sent and recieved with no packet loss

docker exec -ti b24304360fdf ping 283cc0633665
Step 7. From user bash, I tried giving curl http://say-hello/greeting, it gave the following error
Could not resolve host: say-hello

Am I missing any configuration in any of the steps.

What port is the “say-hello” service exposing the service? I see that you have exposed port 8080 on container and 7799 in host on “user” service. Shouldnt that be on “say-hello” service?

Thanks Sreenivas.
Since “say-hello” service uses overlay network, the “user” service need to communicate with “say-hello” service through name rather than IP+port combination.

With service discovery, you should be able to access “say-hello” by service name from “user” service. Can you get the following outputs:
docker network inspect int
docker --version
docker service ps

can you also try “ping say-hello” from “user” exec shell.

Thanks Sreenivas. The issue got resolved.
While accessing the API in say-hello service, I should have used the port as below
instead of http://say-hello/greeting

My understanding is that when we use Eureka server for self registration and discovery, while discovering the services, we use service name without port (http://say-hello/greeting) which will read the IP and port (from eureka) and automatically load balances if there are multiple instances of the same service running.

In docker swarm mode, the difference is that we run a microservice inside a container. When we give “say-hello”, it resolves / discovers the container. The port resolves the running microservice and then the respective API in the microservice.

Another point what I noted is that when we create the service without mentioning the port number, the microservice runs default on 8080 in the container. When we try to access with “say-hello/greeting”, it gives connection refused (not taking the default 8080). It requires port to be mentioned in an explicit manner like “say-hello:8080/greeting”

Its good that you got it resolved.
Regarding this point you mentioned:

  • The above point is not correct. The exposed port depends on how Dockerfile for Container is written. Dockerfile EXPOSE port would dictate exposed port for a container.

It also doesn’t matter much whether the port is exposed or not in this case. Exposing a port merely helps in assigning random published ports to all exposed ports, but one can publish a port and map it explicitly without it being exposed (as is done here).

Here is the contents of Dockerfile

FROM java
ADD target/ /tmp/
ENTRYPOINT [ “sh”, “-c”, “java -jar /tmp/say-hello-0.0.1-SNAPSHOT.jar > /tmp/log.txt”]

I have not exposed the port in Dockerfile.

I will correct my statement. As @tnelis mentioned, EXPOSE merely allows “-P” option to create dynamic random ports on host for each exposed port. It is not necessary to do “EXPOSE” if host access is not needed or if host access is needed and “-p” option is used. Going back to port 8080 you mentioned, I assume that is coming from your Java code itself and not in Docker’s scope.