We get in touch with how to use services on Swarm by starting with a simple sample: Deploy and scale Nginx.
To make this chapter self-sufficient and useful for developers who are reading it as a stand-alone chapter. Let's quickly create a minimal Swarm Mode architecture locally, made of one manager and three workers:
for i in seq 3; do docker-machine create -d virtualbox
node- $i; done
node-1
, which we elect as our static manager, and initialize it on a Swarm:eval $(docker-machine env node-1) docker swarm init --advertise-addr 192.168.99.100
for i in 2 3 4; do docker-machine ssh node-$i sudo docker swarm join --token SWMTKN-1- 4d13l0cf5ipq7e4x5ax2akalds8j1zm6lye8knnb0ba9wftymn- 9odd9z4gfu4d09z2iu0r2361v 192.168.99.100:2377
Swarm Mode architecture is always connected to node-1
by Docker Machine-shell environment variables that are filled by the previous eval
command. We need to check whether all the nodes, including the leader manager, are active and successfully joined to the Swarm:
Now, we can check the status of this Swarm cluster using docker info
command:
The important information here is that Swarm is active, and then some Raft details follow.
A new command introduced in Docker 1.12 is docker service
and that's what we're going to see now. Service is the primary way by which you'll operate applications on Docker Swarm mode; it's how you will create, destroy, scale and roll update services.
Services are made of tasks. An nginx service is made-up of nginx container tasks. The service mechanism spins-up the tasks on (typically) worker nodes. So, when you create a service, you have to mandatorily specify, among its options, a service name and the container that will be the base of the service.
.
The syntax to create the services is very immediate: You just use the docker service create
command, specifying options, such as the exposed ports, and select the container to use. Here we execute
docker service create -p 80:80 --name swarm-nginx --replicas 3
fsoppelsa/swarm-nginx
This command starts nginx, exposes the container's port 80
to the host's port 80
, so that they can be reached from outside, and specifies a replica factor of three.
Replica factor is the way you scale containers on Swarm. If you specify three, Swarm will create three nginx tasks (containers) on three nodes and try to preserve this number, in case one or more of these containers die, by rescheduling nginx on other available hosts (where possible).
If a no --replicas
option is given, then the default replica factor is 1
.
After some time, Swarm needs to pull the image from the hub, or any registry locally, to the hosts and create the appropriate container (and exposing the port); we see that three nginx are in place on our infrastructure with the command:
docker service ls
These tasks are actually scheduled on three nodes, as shown using the following command:
docker service ps swarm-nginx
The fsoppelsa/swarm-nginx
container used here is a trivial modification of richarvey/nginx-php-fpm
, which is a nginx image empowered by PHP. We used PHP to output on the Nginx welcome page the address of the current server, by adding a PHP command with the purpose of showing the load balancing mechanism.
<h2>Docker swarm host <?php echo $_SERVER['SERVER_ADDR']; ?></h2>
Now if you point your browser to the manager IP and reload several times, you'll see that a load balancer is actually redirecting you to different containers sometimes.
First page that will load will be similar to the following screenshot:
The following screenshot shows another page loaded, with a different node selected by the load balancer, 10.255.0.9:
The following screenshot is of another page loaded when the load balancer redirects to node 10.255.0.10: