4

I have stack with 2 services: Spring boot application and mongo database. I want to deploy this stack to Docker Swarm (1 node in Germany, 1 in Finland and 1 in Estonia).

Currently Swarm schedules application to Germany cluster and Database to Finland, which means that every request goes from Germany to Finland.

Is this way how to force Swarm place all pieces of stack to single node ?

P.S. sticking to hostname is not a solution, because if node dies service is down.

My Stack.yml is:

version: '3.3'
services:
app:
  image: kyberorg/boot-mongo
  networks:
  - net
  ports:
    - "8080:8080"
  depends_on:
    - mongo
labels:
  - ee.yadev.bootmongoapp
deploy:
  mode: replicated
  replicas: 1
  update_config:
    parallelism: 1
    delay: 10s
 mongo:
   image: mongo
  networks:
    - net
  volumes:
    - example-mongo:/data/db
  deploy:
    mode: replicated
    replicas: 1
    update_config:
      parallelism: 1
      delay: 10s
networks:
  net:
   driver: overlay
volumes:
  example-mongo:
    external: true
kyberorg
  • 637
  • 1
  • 8
  • 22
  • You can use `binpack` deployment strategy. Docker will do it's best to deploy all the services to single node – WildDev Nov 20 '18 at 18:59

4 Answers4

3

I also spent half a day looking for the solution, and I found it.

Take a look onto Affinity option, which is pretty well described here: https://blog.docker.com/2015/02/scaling-docker-with-swarm/

Affinity In some cases, the placement of a container must be relative to other containers. Swarm lets you define those relationships through affinities.

The following will run two Redis servers, while guaranteeing they don’t get scheduled on the same machine:

docker run -d --name redis_1 -e ‘affinity:container!=redis_’ redis docker run -d --name redis_2 -e ‘affinity:container!=redis_’ redis

Affinities are automatically generated when the relationship between containers is implied. Containers that use options such as –link, –volumes-from and –net=container: get co-scheduled on the same host.

Dmytro Sirant
  • 118
  • 10
1

my first idea is to suggest you to use "placement constraints" and "labels":

https://docs.docker.com/engine/swarm/services/#placement-constraints https://docs.docker.com/engine/swarm/manage-nodes/#add-or-remove-label-metadata

Thanks to them you can assign labels to nodes for each country and then modify your stack in order to force the apps to run on the same node.

docker node update --label-add country=Germany node-germany docker node update --label-add country=Finland node-finland

--constraint node.labels.region==east

version: '3.3' services: app: image: kyberorg/boot-mongo deploy: placement: constraints: - country == Germany

mongo: image: mongo deploy: placement: constraints: - country == Germany

Other useful links:

https://semaphoreci.com/community/tutorials/scheduling-services-on-a-docker-swarm-mode-cluster https://container-solutions.com/using-binpack-with-docker-swarm/

I hope this can help you!

giabar
  • 11
  • 1
  • Thanks for answer. Country labels are not what I'm actually looking for. Because if germal node is down, app is down as well. Binpack strategy is good from me. I attempted to add affinity to ENV vars.But neither affinity.service nor affinity.container succeeded. – kyberorg Nov 19 '18 at 10:50
1

What you are looking for is something like POD in kubernetes where co-location of containers is possible. AFAIK, this is currently not available on docker.

You can have a look at this repo and see if it is useful: https://github.com/rycus86/podlike

It's an attempt to bring the concept of pods to docker.

edit: On a side note, if the app and db are so tightly coupled, it makes sense that both are part of the same container.

vimal-k
  • 293
  • 3
  • 7
1

The architecture of Swarm is one that you usually want a single swarm in the same region due to the latency of managers. Typically a swarm is "single region, multiple availability zones" (datacenters close to each other, in the same city usually.)

I also can't think of a way where you can use either constraints and/or placement preferences to have the two containers together in one datacenter, and then managers move them to the same 2nd datacenter if the first is down.

Podlike, like giabar mentioned, is an option but doesn't solve your "single swarm across multiple regions" design challenge.

Bret Fisher
  • 8,164
  • 2
  • 31
  • 36