In the Docker Swarm Introduction, we wrote about all the advantages of the Docker Swarm and how it can be useful to the companies that have a few (or just one) developers maintaining thousands of containers. This is how Docker Swarm Services will be of great help, specifically.
Docker service command is a new functionality we were given after enabling the Swarm mode. We could say that docker service command in Swarm mode substitutes docker run command when Swarm is not turned on. It is assumed that this has been done in order not to break the existing functionality of docker run command, because the Docker itself was made with the assumption that there is one host, and not more of them. When we talk about a cluster, then we don’t worry about individual nodes, because we will not go to a specific node each time and run or kill specific containers, or change configurations. Swarm will do this for all of us. We will forward the configuration to Swarm and then it will distribute containers according to the instructions specified in the configuration.
To run the service, we use docker service create command. As an example, we can try to ping google.com:
After running a command, if the parameters are correct, we will be given service ID as well as the possibility to track progress. To ensure that our service is still active, we can track logs from that service by calling a command:
In the column replicas we can see how many replicas of that service exist. In our case there is just one replica which is what we were looking for. In other words, in case the number of replicas is not specified, this implies that the value is 1. The job of the orchestrator is to try to make those two numbers equal. If we want to increase the number of replicas we can do that without turning off the current service. What we need to do is just forward the number of replicas we want to, to the existing service by using the command update.
To see what tasks and containers this service has run, we will execute the command docker service ps for the tasks and finally forward the service ID. Also, we will use the command docker container ls for the containers.
The preview of the service, tasks and containers that have been run
In the picture we can see that three tasks are in progress. This is exactly the number of replicas we have specified. Docker itself gives names to the tasks, which is the name of the service with the suffix x, where x represents the ordinal number of the task. Also, we can see three containers, each one is created by a specific task which we were given by running three replicas. Regarding the number of the container, Docker took this over by adding the suffix, which in this case is the task ID, to the name of the task and its ordinal number.
Imagine the difference between docker run command which is used on a local machine mainly for the development environment and production environment where you have more servers. To maintain the number of containers, you need to go from one machine to another and check the number of containers and then decrease or increase them, which is actually the biggest benefit of Swarm.
If we list out all the possible options which we can forward to the docker service update command , we will see that the number of options is really big. This is because the main goal of the service in Swarm is to substitute containers and implement some changes without stopping the entire service, leaving the entire system unavailable to the user. If we would want to change containers in Swarm from the example with three replicas, we could turn off one container, make any necessary changes and then run it while the other two are still working and then we do this over and over again until we replace all three containers. This principle is better known as a rolling update. In this way your system will always be available to the users. This is why we see so many options for update command, because some commands require that the container is restarted, but Swarm will do that in an intelligent way so that the system is always available.
We have seen that all three containers are run. What would happen if one of them stopped working? We can cause this by calling docker container rm and then forward the name of the container. By using this command we will kill one container. If we called docker container ls we would see that only two out of three containers were left. If we wait a few seconds and call docker container ls again, we will see that Swarm ran the third container, because its aim is to make the state of Swarm equal to the state we initially set up, which is to have three replicas.
If we require that the tasks are listed out over our service, we will see that now we have four tasks. Three tasks mark the containers that are run and one task which shows that one container is turned off, that is, that it is no longer active. A new container took over the name from the old container which was turned off. We also see the error that caused that task to stop. All of these are responsibilities of the Orchestrator whose goal is to maintain the desired state of the service which we have assigned.
Whenever we use some docker service command, we actually never define the exact action, that is we require that one container is run. What we actually forward is the desired state of our Swarm to the Orchestrator, who will, depending on the desired and the current state, create tasks which will run or turn off the containers. It might seem that there is not a big difference between whether we will just run containers or let Swarm do that for us. But there are differences. For instance, in case the error occurs while running the container, Swarm will know how to manage it and what it should do to make the system continue to function. This is the biggest difference we should keep in mind.
In the next blog, I will write more about running Swarm that has more nodes, in which case we will need more hosts. This is where Multi-node Swarm can make significant contributions and this blog is coming soon so stay tuned.