Oleg
Oleg

Reputation: 3200

docker swarm . Run some service only once per node

I use docker version

    Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:51 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:15 2018
  OS/Arch:          linux/amd64
  Experimental:     false

And docker-compose for configuring my services. I want to have 3 replicas of a server that run on some specially labeled 3 nodes. For this I use yaml configuration like :

version: '3.7'

services:
  ser:
    deploy:
      placement:
        constraints:
          - "node.labels.cloud.type == nodesforservice"
      replicas: 3
      restart_policy:
        condition: any
      rollback_config:
        delay: 0s
        parallelism: 0
      update_config:
        delay: 6s
        parallelism: 1
    environment:
      - affinity:service!=stackname_servicename
    image: service:latest

and deploy this configuration via

docker stack deploy --compose-file docker-stack.yml stackname

But I have found out that affinity:service!=stackname_servicename does not work properly ( or does not work at all ). It works only in the deprecated standalone mode. If there are only 2 nodes currently available the service will be deployed to some node twice. And it is what I try to avoid.

Is there is any possibility in a docker swarm explicitly say that 2 containers of the same service are not alowed ? I have found only posibility to create global services with --mode global but I need only 3 instances and not more.

Upvotes: 2

Views: 2712

Answers (2)

gohm'c
gohm'c

Reputation: 15480

if you are using docker create service, you can use --replicas-max-per-node 1 to enforce 1:1 relationship between container and node.

if you are using compose file you can declare max_replicas_per_node under:

deploy:
  placement:
    max_replicas_per_node: 1

if you need further control on which node can run the container using label, place the label matching at constraint block under placement.

More details here: Compose and Docker compatibility matrix

Upvotes: 3

Metin
Metin

Reputation: 741

This is a rather old thread, but using a node label as placement constraint in combination with global mode deployment does the trick.

deploy:
  mode: global
  placement:
    constraints:
      - node.labels.cloud.type == nodesforservice

Of course the node label "cloud.type=nodesforservice" needs to be applied to the desired number of nodes.

For Docker swarm there is no such thing as affinity.

Upvotes: 1

Related Questions