Creating and Scaling a Service

docker service create takes most of docker run's options plus cluster ones such as --replicas, --mode global (one task per node) and --constraint. It records a desired state, and the manager schedules tasks until reality matches. traefik/whoami, a tiny server that answers with its container's hostname, makes placement and load balancing visible:

A two-replica service, scaled to fiveShell
m1 service create -q --detach=false --name whoami --replicas 2 -p 8080:80 \
  l3-registry:5000/whoami:1.12 >/dev/null
m1 service ls --format '{{.Name}} {{.Replicas}} {{.Ports}}'
m1 service scale -d whoami=5 >/dev/null; sleep 8
m1 service ps whoami --format '{{.Node}}' | sort | uniq -c
for n in $(seq 10); do curl -s $IP1:8080 | grep Hostname; done | sort | uniq -c
m1 service rm whoami >/dev/null
Output
whoami 2/2 *:8080->80/tcp
      2 swarm-1
      2 swarm-2
      1 swarm-3
      2 Hostname: 1b98fb7c087d
      2 Hostname: 534cbac97891
      2 Hostname: 7fcfc38fe87d
      2 Hostname: 823a31867be6
      2 Hostname: f4a7b95684d5

The scheduler spread the tasks over all three nodes, and each node pulled the image itself, which is why a swarm needs a registry. Ten requests to swarm-1 reached all five replicas, two each (Routing Mesh explains how). Remove a task's container by hand (docker exec l3-swarm-2 docker rm -f <id>) and the manager starts a replacement within seconds, keeping the failed task in service ps history.