Search code examples
dockerdocker-composedocker-swarm

Docker Stack Swarm - Service Replicas are not spread for Mutli Service Stack


I have deployed a stack with a of 4 services on two hosts (docker compose version 3). The services are Elasticsearch, Kibana. Redis, Visualiser and finally my Web App. I have't set any resource restrictions yet. I spun two virtual host via docker-machine , one with 2GB and one with 1GB. Then I increased the replicas of my web app to 2 replicas, which resolved to the following distribution:

Host1 (Master): Kibana, Redis, Web App, Visualiser, WebApp

Host2 (Worker): Elasticsearch

Why is the Swarm Manager distributing both Web App Containers to the same host. Wouldn't it be smarter if Web App is distributed to both hosts? Besides node tagging I couldn't find any other way in the docs to influence the distribution. Am I missing something?

Thanks

Bjorn

docker-compose.yml

version: "3"
services:
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
    environment:
      ES_JAVA_OPTS: -Xms1g -Xmx1g
    ulimits:
      memlock: -1
      nofile:
        hard: 65536
        soft: 65536
      nproc: 65538
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 1g
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - webnet


  web:
    # replace username/repo:tag with your name and image details
    image: bjng/workinseason:swarm
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
    ports:
      - "80:6000"
    networks:
      - webnet

  kibana:
    image: docker.elastic.co/kibana/kibana:5.4.3
    deploy:
      placement:
        constraints: [node.role == manager]
    ports:
      - "5601:5601"
    networks:
      - webnet

  redis:
    image: "redis:alpine"
    networks:
      - webnet



volumes:
  esdata:
    driver: local


networks:
  webnet:

Solution

  • Docker schedules tasks (containers) based on available resources; if two nodes have enough resources, the container can be scheduled on either one.

    Recent versions of Docker use "HA" scheduling by default, which means that tasks for the same service are spread over multiple nodes, if possible (see this pull request) https://github.com/docker/swarmkit/pull/1446