Search code examples
dockerdocker-composedocker-swarm

host name not working with docker swarm mode


I am using docker version 18.06.1-ce and compose version 1.22.0.

As per docker, it should be possible to call services using service names. This is working for me with docker compose without swarm mode, but on swarm mode it is not working. I have even tried setting aliases in my compose but no result.

Below is my docker-compose.yml

version: "3"

networks:
  my_network:
    external:
      name: new_network


services:
  config-service:
    image: com.test/config-service:0.0.1
    deploy:
      placement:
        constraints: [node.role == manager]
      resources:
        limits:
          memory: 1024M
        reservations:
          memory: 768M
      restart_policy:
        condition: on-failure
    healthcheck:
      test: ["CMD", "curl", "-f", "http://config-service:8888/health"]
      interval: 5s
      timeout: 3s
      retries: 5
    ports:
      - 8888:8888
    networks:
      my_network:
        aliases:
          - config-service

  eureka-service:
    image: com.test/eureka-service:0.0.1
    deploy:
      placement:
        constraints: [node.role == manager]
      resources:
        limits:
          memory: 1536M
        reservations:
          memory: 1024M
      restart_policy:
        condition: on-failure
    healthcheck:
      test: ["CMD", "curl", "-I", "http://eureka-service:8761/health"]
      interval: 5s
      timeout: 3s
      retries: 5
    ports:
      - 8761:8761
    depends_on:
      - config-service
    networks:
      my_network:
        aliases:
          - eureka-service

When I inspect into my network I found

[
    {
        "Name": "new_network",
        "Id": "s2m7yq7tz4996w7eg229l59nf",
        "Created": "2018-08-30T13:58:59.75070753Z",
        "Scope": "swarm",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "355efe27067ee20868455dabbedd859b354d50fb957dcef4262eac6f25d10686": {
                "Name": "test_eureka-service.1.a4pjb3ntez9ly5zhu020h0tva",
                "EndpointID": "50998abdb4cd2cd2f747fadd82be495150919531b81a3d6fb07251a940ef2749",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            },
            "5cdb398c598c1cea6b9032d4c696fd1581e88f0644896edd958ef59895b698a4": {
                "Name": "test_config-service.1.se8ajr73ajnjhvxt3rq31xzlm",
                "EndpointID": "5b3c41a8df0054e1c115d93c32ca52220e2934b6f763f588452c38e60c067054",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

Now if I connect into containers terminal and ping using the long name 'test_config-service.1.se8ajr73ajnjhvxt3rq31xzlm' it is able to ping but not 'config-service'.


Solution

  • I believe the issue you are experiencing is because you are using a swarm scoped bridge network, instead of an overlay network. I'm not sure if this configuration is supported. The DNS entry for the service when deployed in swarm mode is at the service level, not the individual containers. From my testing, that DNS entry, along with the code to setup a VIP, only appear to work with overlay networks. You may want to follow this issue if you really need your network to be configured as a bridge: https://github.com/moby/moby/issues/37672

    Otherwise, the easy fix is to replace your network with an overlay network. You can remove your network aliases since they are redundant. And if you have other containers on the host that need to also be on this network, from outside of swarm mode, be sure to configure your overlay network as "attachable". If you have other applications currently attached to the network, you can replace that with a new network, or if you need to keep the same network name, swap it out in two phases:

    # create a temporary network to free up the new_network name
    docker network create -d overlay --attachable temp_network
    docker network connect temp_network $container_id # repeat for each container
    # finish the above step for all containers before continuing
    docker network disconnect new_network $container_id #repeat for each container
    # remove the old bridge network
    docker network rm new_network
    
    # now create a new_network as overlay
    docker network create -d overlay --attachable new_network
    docker network connect new_network $container_id # repeat for each container
    # finish the above step for all containers before continuing
    docker network disconnect temp_network $container_id #repeat for each container
    # cleanup the temporary network
    docker network rm temp_network
    

    If everything is running in swarm mode, then there's no need for --attachable. After that, you should be able to start your swarm mode stack.