Search code examples
dockerdocker-composeswarm

Disable external node service accessibility in docker swarm


I have a docker swarm with 2 nodes and each node run 2 services in global mode so each node have 2 services running inside it.
My problem is how to force ubuntu service in node1 only connect to mysql service in node1 and dont use round-robin method to select mysql service. so when I connect to mysql from ubuntu in node1 with mysql -hmysql -uroot -p it select only mysql in node1.


here is the docker-compose file which describes my case

version: '3.8'
services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      app-net: {}
    deploy:
      mode: global
  ubuntu:
    entrypoint: tail -f /dev/null
    deploy:
      mode: global
    image: ubuntu:20.04
    networks:
      app-net: {}
networks:
  app-net: {}

with this docker-compose file inside ubuntu container when I try to connect to mysql it selects mysql service in both nodes with round-robin algorithm. What I try to achieve is to force each service be only visible to the services inside the same node.


Solution

  • I can't think of an easy way to achieve what you want in swarm with an overlay network. However, you can use unix socket instead of network. Just create a volume, mount it both into MySQL and your application, then make MySQL to put its socket onto that volume. Docker will create a volume on each node and thus you'll have your communication closed within node.

    If you insist on using network communications, you can mount node's Docker socket into your app container and use it to find name of the container running MySQL on that node. Once you got the name, you can use it to connect to the particular instance of the service. Now, not only it is hard to make, it is also an anti-pattern and a security threat, so I don't recommend you to implement this idea.

    At last there is also Kubernetes, where containers inside a pod can communicate with each other via localhost but I think you won't go that far, will you?