DCA 10 - Docker Services on Specific Nodes

Jarret B

Well-Known Member
Staff member
May 22, 2017
Reaction score
If you run Docker in a single system, not in a Swarm, then you control the containers and services on the system. If you run a Swarm, you can start containers and services, but which Node they run on is controlled by the Swarm Manager.

What if you want a container to run on a specific Node?

Node Hostname

If I were to run 'docker node ls', I get a listing of all the Nodes in the Swarm. In my case, the Nodes have a Hostname of 'Docker1', 'Docker2', and 'Docker3', as shown in Figure 1.

Figure 1.JPG


We can use the Hostnames to specify which Node the container will run on in the Swarm.

Before choosing the Hostname method, be aware that if the system cannot be reached properly by the Hostname, such as a Ping, this will fail.

Currently, I still have the image for 'httpd', so I will use this image. If you do not have it on your swarm, pull it from the repository.

We will create an 'httpd' service on 'Docker3' with two replicas. By using the Hostname, we specify '--constraint 'node.hostname == Docker3', we can set the specific Node.

docker service create --name web3 -p 80:80 --constraint 'node.hostname == Docker3' --replicas 2 httpd

Once run, you should be notified that two tasks were performed and the services were started. You can check them by running 'docker service ps web3', as shown in Figure 2.

Figure 2.JPG


You can see in Figure 2 that there are two containers, both 'web3.1' and 'web3.2', running on Docker3.

If you do not want want to depend on the Hostname for creating the service, then you can try using a Node Label.

NODE: To remove the service, it is done as normal, use the command 'docker service rm web3'. The command will work on all these methods.

Node Labels

When a Node is created, there is no label assigned to the Node. You can use the command 'docker node inspect node Docker2', for instance. There is no label listed, as you can see with the command 'docker node inspect node Docker 2 | less'. If nothing else has been modified, it should be on the first page and around Line 11. If there is nothing after 'Labels :' other than '{}' then the label has been removed.

NOTE: In this example, I will switch to 'Docker2', and then switch back and forth between the two for the remaining sections. This can help show how to use a different Node.

So, let's create a label. Let's label 'Docker2' as 'D2'. Use the command 'docker node update --label-add node=D2 pfpui0pn8jdj67lilk8eo5269'. Here, we use the ID of the Node from the command 'docker node ls', as shown in Figure 1. If you don't want to use 'grep' to find the label, use the command 'docker node inspect node Docker2 | less'.

All we did was create a label 'node=D2'. Of course, 'D2' can be whatever we want, as long as it is a legally usable name. Stick with alphanumeric characters only to be safe. You can also change 'node' to anything usable as well. Just remember what both options are for use later. If needed, just perform an inspect of the Node to verify the options you used.

You can place the same label on multiple Nodes so that the Node has a backup if it should fail.

Our Node has a label, so we need to start a service on the labeled Node. Use the following command:

docker service create --name web2 -p 80:80 --constraint 'node.labels.node == D2' --replicas 3 httpd

You can remove the label with just the first option of the label, in our example, 'node', with the command 'docker node update --label-rm node Docker2' or ' docker node update --label-rm node pfpui0pn8jdj67lilk8eo5269'. In most cases, you can use the Hostname instead of the ID, but it might be best to always use the ID. I just wanted to show it would work.

Keep in mind that you can specify multiple labels on each Node. In our example, we could name it 'node=Docker2', 'swarm-node=D2', and anything else we may want.

Node ID

We can use an existing value, instead of creating a label, such as the Node ID.

In this example, I will use the Node ID as shown in Figure 1. Remember, to get the Node ID, use the command 'docker node ls'. The Node ID will be shown for all Nodes in the Swarm. In my case, I am using Node 3, or 'Docker3'. The Node ID is '475x5sew375aextqz9elogjxj'. I am creating four replicas of the 'httpd' service. The command is:

docker service create --name http3 -p 80:80 --constraint 'node.id == 475x5sew375aextqz9elogjxj' --replicas 4 httpd

You can see the services running with the command 'docker service ps http3'.

Node Role

There are two options for specifying a role. You can choose either the 'worker' or the 'manager'. The 'manager' is the 'leader' node as shown in the command 'docker node ls'.

The worker nodes are those that aren't manager nodes.

Of course, this doesn't limit the Node to a specific one, but for most Swarms, the manager system is the 'main' hardware that is usually running other services already. Every Swarm is different anyway.

So, let's set up a service to run on the workers:

docker service create --name http -p 80:80 --constraint 'node.role == worker' --replicas 4 httpd

If I run the command 'docker service ps http', I can see that two tasks are on 'Docker2' and two on 'Docker3', as shown in Figure 3.

Figure 3.JPG


Keep in mind that if a new worker Node is added to the Swarm, the service can start on it.

You can promote a 'Worker' to a 'Manager with the command:

docker node promote Docker2

This would make 'Docker2' a Leader as well as 'Docker1'. You can specify multiple Nodes to promote by separating them with a space. If you list the nodes, 'docker node ls', the current Manager will be listed as 'Leader' and the other managers are listed as 'Reachable'. A 'Reachable' Node can become a manager if the 'Leader' fails or is demoted.

To demote a Node to a 'Worker', use the command 'docker node demote Docker2'. Multiple Nodes can be specified by separating them with a space.

Again, this will move the service that is dependent on the 'Role'.

Node Platform OS

If you have a Swarm set up that crosses Operating Systems (OS), then you can set which services can run on which Node Host OS.

You can use the command 'docker node inspect Docker1 | grep OS' to see the OS that is specified for the Node. The options are 'linux', 'windows' and others. So, you may want a service to only run on 'linux' systems, so use the command:

docker service create --name linux-http -p 80:80 --constraint 'node.platform.os == linux' --replicas 3 httpd

All systems, 'workers' and 'managers', that have the Linux OS could run the 'linux-http' service.

Node Platform Arch

We can specify the OS, so we can also limit the service to a specific hardware architecture.

Some examples are: 'x86_64', '386', 'arm64', etc. You can find the value using the command: 'docker node inspect Docker1 | grep Architecture'.

Let's assume we have some 'arm64' Nodes that we wanted to use for our web server. We can specify that these systems are used for the web service by the architecture:

docker service create --name webservice -p 80:80 --constraint 'node.platform.arch == arm64' --replicas 5 httpd

We know exactly which Nodes can run the web service.


Some of these parameters you may never use in a Swarm, but it is nice to know they are there.

Practice these a bit and see how they work to manage services. Of course, I only did one service at a time, but you can have multiple running on various systems at the same time. So, if you have multiple services, you can have one using labels and another using hostname. These can be fine-tuned as you need to manage which Nodes are being used by services.

Members online

Latest posts