How to update docker stack without restarting all services - docker

I have a swarm cluster wherein different technology dockers are deployed. (Zookeeper, Kafka, Elastic, Storm and custom web application)
Web application goes under tremendous changes and have to update the stack everytime web docker changes. Once in a while there will be updates to Elasticsearch image.
When i run docker stack deploy, it goes and restarts all existing docker services which are not even changed. This hampers whole stack and there is a downtime for whole application. Docker stack does not have option of update.
Someone has solution for this?

docker service update --image does the trick.
Check the docker service update docs.

Redeploying the stack with changed configuration(docker-compose.yml file) solves the problem see https://docs.docker.com/engine/reference/commandline/stack_deploy/#extended-description.
There they stated "Create and update a stack from a compose or a dab file on the swarm." Also i dont see any command like 'docker stack update
'. So this can solve the problem.

If you have docker stack created from compose.yml and you need to re-deploy only one service from stack, just do this:
docker service rm <your-service>
and then:
docker stack deploy -c compose.yml <stack-name>
And you just will update your stack, not recreate all services.

Related

How to restart a docker stack container by cron? [duplicate]

Does anyone know if there is a way to have docker swarm restart one service that is part of a stack without restarting the whole stack?
Doing docker stack deploy again for me is the way to go to update services. As Francois' Answer, and also in my own experience, doing so updates only services that need to be updated.
But sometimes, it seems easier when testing stuff to only restart a single service. In my case, I had to clear the volume and update the service to start it like it was fresh. I'm not sure if there is downside to the method I will describe. I tested it on my development stack and it worked great for me.
Get the service id you want to tear down then use docker service update --force <id> to force the update of the service which effectively re-deploy it
$ docker stack services <stack_name>
ID NAME ...
3xrdy2c7pfm3 stack-name_api ...
$ docker service update --force 3xrdy2c7pfm3
The --force flag will force the service to update causing it to restart.
Scale to 0 and back up:
docker service scale myservice=0
docker service scale myservice=10
Looking at the docker stack documentation:
Extended description
Create and update a stack from a compose or a dab file on the swarm
From this blog article: docker stack works in a similar way as docker compose. It’s idempotent. If the stack is already deployed, docker stack deploy will restart only those services which has the digest or tag that is updated:
From my experience, when I deploy the same stack again with one service changing, only the updated service will be restarted.
BUT... there seems to be some limitations to changes that are taken into account (some report bugs with image tags), so give it a try and see if works as expected.
You can also use service update if you want to be sure that only targeted service if updated with your changes.
You can also refer to this similar SO QA.
As per the example in the documentation for rolling updates:
$ docker service update --image redis:3.0.7 redis
However, that only works if your image is already on the local machines. If not then you need to use --with-registry-auth to send registry authentication details to the swarm agents. See details in the docker service update documentation.
$ docker service update --with-registry-auth --image redis:3.0.7 redis
To restart a single service (with rolling restart to avoid downtime in case the service has multiple replicas) in already configured, existing stack, you can do:
docker service update --force stack_service_name
I don't recommend running the same command again (in another shell) until this one completes (because otherwise the rolling restart isn't guaranteed; it might restart all replicas of that service).
The docker service update command also checks for newer version of the image:tag you are trying to use.
If your registry requires auth, also pass --with-registry-auth argument, like so:
docker service update --force --with-registry-auth stack_service_name
If you don't pass this argument, the service will still be restarted, but the check won't be made and the service will still use the old container image without pulling the new one first. Which might be what you want.
In case you want to also switch to different image tag (or completely different image), you can do it from here too, but remember to also change the tag in your docker-stack.yml, or your next docker stack deploy will revert it back to the verison defined there:
docker service update --with-registry-auth --force --image nginx:edge stack_service_name
remove it:
docker stack rm stack_name
redeploy it:
docker stack deploy -c docker-compose.yml stack_name

it's posible add a new service into a stack in docker without update the .yml document?

I'm trying to add to a deployed docker stack a new service without update the .yml document
my code is
docker stack deploy -c app.yml app
Add a new service
docker service create --name app_newservice --network app_network app_image:0.1
To visualise if the stack add the new service i run
docker stack services app
But after i run my commands, i can interact with my new added container because is in the same network, but is not listed in the same stack, the problem is i dont know if my stack is well admistrated by the swarm
https://i.imgur.com/kI1pCkv.png
app_nginx................. app
app_otherservice...... app
app_newservice........ ----
app_portainer........... app
I spect the new service listed into the stack. It's posible?
Well it can't be. it's completely needed update the full .yml to correctly update the stack.

docker swarm services stuck in preparing

I have a swarm stack deployed and I removed couple services from the stack and tried to deploy them again. these services are showing with desired state remove and current state preparing .. also their name got changed from the custom service name to a random docker name. swarm also trying to start these services which are also stuck in preparing. I ran docker system prune on all nodes and them removed the stack. all the services in the stack are not existent anymore except for the random ones. now I cant delete them and they still in preparing state. the services are not running anywhere in the swarm but I want to know if there is a way to remove them.
I had the same problem. Later I found that the current state, 'Preparing' indicates that docker is trying to pull images from docker hub. But there is no clear indicator in docker service logs <serviceName> available in the docker-compose-version above '3.1'.
But it sometimes imposes the latency due to n\w bandwidth or other docker internal reasons.
Hope it helps! I will update the answer if I find more relevant information.
P.S. I identified that docker stack deploy -c <your-compose-file> <appGroupName> is not stuck when switching the command to docker-compose up. For me, it took 20+ minutes to download my image for some reasons.
So, it proves that there is no open issues with docker stack deploy,
Adding reference from Christian to club and complete this answer.
Use docker-machine ssh to connect to a particular machine:
docker-machine ssh <nameOfNode/Machine>
Your prompt will change. You are now inside another machine. Inside this other machine do this:
tail -f /var/log/docker.log
You'll see the "daemon" log for that machine. There you'll see if that particular daemon is doing the "pull" or what's is doing as part of the service preparation. In my case, I found something like this:
time="2016-09-05T19:04:07.881790998Z" level=debug msg="pull progress map[progress:[===========================================> ] 112.4 MB/130.2 MB status:Downloading
Which made me realise that it was just downloading some images from my docker account.

docker service update vs docker stack deploy with existing stack

I have a doubt in using docker swarm mode commands to update existing services after having deployed a set of services using docker stack deploy.
As far I understood every service is pinned to the SHA256 digest of the image at the time of creation, so if you rebuild and push an image (with same tag) and you try to run a docker service update, service image is not updated (even if SHA256 is different). On the contrary, if you run a docker stack deploy again, all the services are updated with the new images.
I managed to update the service image also by using docker service update --image repository/image:tag <service>. Is this the normal behavior of these commands or is there something I didn't understood?
I'm using Docker 17.03.1-ce
Docker stack deploy documentation says:
"Create and update a stack from a compose or a dab file on the swarm. This command has to be run targeting a manager node."
So the behaviour you described is as expected.
Docker service update documentation is not so clear but you yourself said it only runs with --image repository/image:tag <service> so the flag is necessary to update the image.
You have two ways to accomplish what you want.
It is normal and expected behavior for docker stack deploy to update images of existing services to whatever hash the specified tag is linked.
If no tag is present, latest is assumed - which can be problematic at times, since the latest tag is not well understood by most persons, and thus lead to some unexpected results.

docker create service vs. docker deploy stack

The new Docker 1.13.0 release introduced docker stack deploy.
docker stack deploy adds support of deploying services from a docker-compose.yml file directly.
Are the command docker service create and docker deploy stack creating the same service, just i two different ways?
Are there any special features added the service by creating it with docker deploy stack?
Im a bit confused, and can't find any information about this subject.
Thanks in advance
A stack is a collection of services. This is similar to how a compose file defines a group of containers to run. So if you only need to run a single service, you can do so with a docker service create. If you need to deploy a collection of services, or use a definition from a compose file as your definition for the service(s), then you would deploy them with docker stack deploy.

Resources