Let's say we have the following stack file:
version: "3"
services:
ubuntu:
image: ubuntu
deploy:
replicas: 2
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
entrypoint:
- tail
- -f
- /dev/null
logging:
driver: "json-file"
ports:
- "80:80"
networks:
- webnet
web:
image: httpd
ports:
- "8080:8080"
hostname: "apache"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
resources:
limits:
memory: 32M
reservations:
memory: 16M
depends_on:
- "ubuntu"
networks:
- webnet
networks:
webnet:
When I run docker service inspect mystack_web the output generated does not show any reference to the depends_on entry.
Is that okay? and how can I print the dependencies of a given docker service?
The depends_on isn't used on docker swarm:
The depends_on option is ignored when deploying a stack in swarm mode with a version 3 compose file. - from Docker Docs
Another good explanation on GitHub:
depends_on is a no-op when used with docker stack deploy. Swarm mode services are restarted when they fail, so there's no reason to delay their startup. Even if they fail a few times, they will eventually recover. - from GitHub
Related
I'm trying to deploy a gitlab runner stack in docker-compose above:
version: '3.8'
services:
dind:
image: docker:stable
deploy:
mode: replicated
placement:
constraints:
- "node.role==worker"
restart_policy:
condition: any
volumes:
- /var/lib/docker
command:
- --storage-driver=overlay2
networks:
- netrunner
runner:
image: gitlab/gitlab-runner:alpine
deploy:
mode: replicated
placement:
constraints:
- "node.role==worker"
restart_policy:
condition: any
volumes:
- ./gitlab/runner:/etc/gitlab-runner:Z
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DOCKER_HOST=tcp://dind:2375
depends_on:
- dind
networks:
- netrunner
register-runner:
image: gitlab/gitlab-runner:alpine
deploy:
mode: replicated
placement:
constraints:
- "node.role==worker"
restart_policy:
condition: none
volumes:
- ./gitlab/runner:/etc/gitlab-runner:Z
command:
- register
- --non-interactive
- --locked=false
- --name=Docker Runner
- --executor=docker
- --docker-image=docker:stable
- --docker-volumes=/var/run/docker.sock:/var/run/docker.sock
environment:
- CI_SERVER_URL=https://gitlab.com/
- REGISTRATION_TOKEN=xxxxxxxxxxxxxx
networks:
- netrunner
networks:
netrunner:
driver: overlay
driver_opts:
foo: "1"
Then, with docker swarm initialized, I try the deployment with this pattern:
docker stack deploy --compose-file docker-compose.yml ci
After that, when I check services I get this:
$ docker stack services ci
ID NAME MODE REPLICAS IMAGE PORTS
8ahvxamblhmc ci_dind replicated 0/1 docker:stable
fli2u5wszrvp ci_register-runner replicated 0/1 gitlab/gitlab-runner:alpine
zftmedknrwma ci_runner replicated 0/1 gitlab/gitlab-runner:alpine
I'm testing all the steps in docker playground using one manager and three workers. I have tried lots of variation of the compose.yml above. That one is the closest to correct, in my opinion.
Replicas are not running. What should I do ?
My docker-compose.yml is as follow:
version: "3"
services:
write:
image: apachegeode/geode:1.11.0
container_name: write
hostname: a.b.net
expose:
- "8080"
- "10334"
- "40404"
- "1099"
- "7070"
ports:
- "10220:10334"
volumes:
- ./scripts/:/scripts/
command: /scripts/sleep.sh gfsh start locator ...
networks:
my-network:
deploy:
replicas: 1
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.50'
memory: 512M
restart_policy:
condition: on-failure
depends_on:
- read
read:
image: apachegeode/geode:1.11.0
container_name: read
hostname: a.b.net
expose:
- "8080"
- "10334"
- "40404"
- "1099"
- "7070"
ports:
- "10221:10334"
volumes:
- ./scripts/:/scripts/
command: /scripts/sleep.sh gfsh start locator ...
networks:
my-network:
deploy:
replicas: 1
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.50'
memory: 512M
restart_policy:
condition: on-failure
networks:
my-network:
container_name has to be "write" and "read" since they are unique containers but running on the host machine. Setting hostname: a.b.net in the docker-compose.yml sets 192.168.160.2 a.b.net a in /etc/hosts file but /etc/hostname show a which is only the alias name . How can I set /etc/hostname with a.b.net using docker-compose.yml ? I use
docker-compose -f my-docker-compose.yml up -d
to run the containers.
I just completed the docker documentation and created two instances on aws (http://13.127.150.218, http://13.235.134.73). The first one is manager and the second one is the worker. Following is the composed file I used to deploy
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "80:80"
networks:
- webnet
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
redis:
image: redis
ports:
- "6379:6379"
volumes:
- "/home/docker/data:/data"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet:
Here the redis service has the constraint that restricts it to run only on manager node. Now my question is how the web service on worker instance is supposed to use the redis service.
You need to use the hostname parameter in all container, so you can use this value to access services from worker or to access from worker the services on manager.
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
hostname: "web"
deploy:
replicas: 5
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "80:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
hostname: "visualizer"
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis
hostname: "redis"
ports:
- "6379:6379"
volumes:
- "/home/docker/data:/data"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet:
In addictional if you use the portainer instead of visualizer you can control you SWARM stack with more options:
https://hub.docker.com/r/portainer/portainer
BR,
Carlos
Consider the stack file as per the below example -
Regardless of where it is placed manager|worker all the services in the stack file being on the same network can use the embedded DNS functionality which helps to resolve each service by the service name defined.
In this case the service web makes use of service redis by its service name.
Here is an example of the ping command able to resolve the service web from within the container associated with the redis service -
Read more about the Swarm Native Service Discovery to understand this.
I created a docker-compose.yml file containing two services that are run on two different nodes. The two services are meant to communicate on the same port as client and server. Below is my docker-compose.yml file.
version: "3"
services:
service1:
image: localrepo/image1
deploy:
placement:
constraints: [node.hostname == node1]
replicas: 1
resources:
limits:
cpus: "1"
memory: 1000M
restart_policy:
condition: on-failure
ports:
- 8000:8000
networks:
- webnet
service2:
image: localrepo/image2
deploy:
placement:
constraints: [node.hostname == node2]
replicas: 1
resources:
limits:
cpus: "1"
memory: 500M
restart_policy:
condition: on-failure
ports:
- "8000:8000"
networks:
- webnet
networks:
webnet:
When I issue docker stack deploy -c I get error, reading
> Error response from daemon: rpc error: code = 3 desc = port '8000' is already in use by service.
In this thread I read that deploying a service in a swarm makes the port accessible throughout any node in the swarm. If I understand correctly, that makes the port occupied by any node in the cluster. In the same thread, it was suggested to use mode=host publishing, which will only expose the port on the actual host that the container runs. I applied that in the port as:
ports:
- "mode=host, target=8000, published=8000"
Making that change in both service and trying to issue docker stack gives another error:
> 1 error(s) decoding:
* Invalid containerPort: mode=host, target=8000, published=8000
Does anyone know how to fix this issue?
p.s: I tried both "Version3" and "Version3.2" but the issue didn't solve.
I don't know how did you specify host mode since your docker-compose.yml doesn't represent host mode anywhere.
Incidentally, try with long syntax which can specify host mode in docker-compose.yml file.
This long syntax is new in v3.2 and the below is the example(I check it works)
(This is compatible docker engine version against docker-compose syntax version.)
version: '3.4' # version: '3.2' also will works
networks:
swarm_network:
driver: overlay
services:
service1:
image: asleea/test
command: ["nc", "-vlkp", "8000"]
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.hostname == node1
ports:
- published: 8000
target: 8000
mode: host
networks:
swarm_network:
service2:
image: asleea/test
command: ["nc", "service1", "8000"]
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.hostname == node2
ports:
- published: 8000
target: 8000
mode: host
networks:
swarm_network:
The problem is fixed after upgrading to the latest docker version, 18.01.0-ce
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:
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