Service Discovery under Docker Swarm Mode
Service Discovery under Swarm Mode.
Purpose
The purpose of this lab is to illustrate how Service Discovery works under Swarm Mode.
The application
WordPress is an open-source content management system (CMS) based on PHP and MySQL. It is a very simple containers application often used for demo purposes during meetup and conferences.
Init your swarm
Let’s create a Docker Swarm first. Open up the first instance and initiate Swarm mode cluster.
docker swarm init --advertise-addr $(hostname -i)
This node becomes a master node. The output displays a command to add a worker node to this swarm as shown below:
Swarm initialized: current node (xf323rkhg80qy2pywkjkxqusp) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-089phhmfamjor1o1qj8s0l4wdhyvegphg6vtt9p3s8c35upltk-eecvhhtz1f2vpjhvc70v6v
vzb \
10.0.50.3:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructi
ons.
The above token ID is unique for every swarm mode cluster and hence might differ for your setup. From the output above, copy the join command (watch out for newlines).
Next, Open up the new instance and paste the below command. This should join the new node to the swarm mode cluster and this new node becomes a worker node. In my case, the command would look something like this:
docker swarm join \
--token SWMTKN-1-089phhmfamjor1o1qj8s0l4wdhyvegphg6vtt9p3s8c35upltk-eecvhhtz1f2vpjhvc70v6v
vzb \
10.0.50.3:2377
Output:
$ docker swarm join --token SWMTKN-1-089phhmfamjor1o1qj8s0l4wdhyvegphg6vtt9p3s8c35upltk-eecvhh
tz1f2vpjhvc70v6vvzb 10.0.50.3:2377
This node joined a swarm as a worker.
Show members of swarm
Type the below command in the first terminal:
docker node ls
The output shows you both the manager and worker node indicating 2-node cluster:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xf323rkhg80qy2pywkjkxqusp * node1 Ready Active Leader
za75md1p0hpc2qswefj8uyktk node2 Ready Active
If you try to execute an administrative command in a non-leader node worker
, you’ll get an error. Try it here:
docker node ls
Create an overlay network
docker network create -d overlay net1
The above command generates an ID:
4md6wyy0pdpdzku6dj2z7yxjf
List out the newly created overlay network using the below command:
docker network ls
The output should show the newly added network called “net1” holding swarm scope .
NETWORK ID NAME DRIVER SCOPE
c30f13d9c242 bridge bridge local
990fa0ad6ab6 docker_gwbridge bridge local
c60123ff7abf host host local
v7sp7ev6xfoo ingress overlay swarm
4md6wyy0pdpd net1 overlay swarm
333c7d045239 none null
Creating MYSQL service
docker service create \
--replicas 1 \
--name wordpressdb \
--network net1 \
--env MYSQL_ROOT_PASSWORD=mysql123 \
--env MYSQL_DATABASE=wordpress \
mysql:latest
The above command creates a service named “wordpressdb” which belongs to “net1” network which runs a single replica of the container. It displays service ID as an output as shown:
ip9a8zl9rke256q92itgrm8ov
Run the below command to list out the service:
docker service ls
The output should be like the following one (your ID will display different though).
ID NAME MODE REPLICAS IMAGE
ip9a8zl9rke2 wordpressdb replicated 1/1 mysql:latest
Let’s list the tasks of the wordpressdb service.
docker service ps wordpressdb
You should get an output like the following one where the 1 task of the service are listed.
ID NAME IMAGE NODE DESIRED STATE
CURRENT STATE ERROR PORTS
puoe9lvfkcia wordpressdb.1 mysql:latest node1 Running
Running about a minute ago
Creating WordPress service
docker service create \
--replicas 4 \
--name wordpressapp \
--network net1 \
--env WORDPRESS_DB_HOST=wordpressdb \
--env WORDPRESS_DB_PASSWORD=mysql123 \
wordpress:latest
The above command creates a service named “wordpressapp” which belongs to “net1” network which runs 4 copies of wordpressapp container. As output, this command displays a service ID as:
m4hca6rliz8wer2aojayv01r5
Listing out the services:
docker service ls
Output:
ID NAME MODE REPLICAS IMAGE
ID NAME MODE REPLICAS IMAGE
ip9a8zl9rke2 wordpressdb replicated 1/1 mysql:latest
m4hca6rliz8w wordpressapp replicated 4/4 wordpress:late
st
You can list the tasks of the wordpressapp service using the command:
docker service ps wordpressapp
Output:
ID NAME IMAGE NODE DESIRED STATE
CURRENT STATE ERROR PORTS
zg7wpvs1rbki wordpressapp.1 wordpress:latest node2 Running
Running 58 seconds ago
8rybe5m4urik wordpressapp.2 wordpress:latest node1 Running
Running about a minute ago
scia4v5i1znj wordpressapp.3 wordpress:latest node2 Running
Running 58 seconds ago
4avyixggcb8n wordpressapp.4 wordpress:latest node1 Running
Running about a minute ago
Service Discovery
Let us try to discover wordpressdb service from within one of wordpressapp container. Open up the manager node instance and run the below command:
Open up instance of worker node and verify what containers are running:
docker ps
This should display number of tasks(containers) running on the worker node locally:
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
52f16028e12c wordpress:latest "docker-entrypoint..." 2 minutes ago Up 2 minu
tes 80/tcp wordpressapp.1.zg7wpvs1rbkiy4zwo71yk031i
f3271e89d54e wordpress:latest "docker-entrypoint..." 2 minutes ago Up 2 minu
tes 80/tcp wordpressapp.3.scia4v5i1znj378gujluad2ku
As shown above, there are 2 instances of wordpressapp task(container) running on the worker node.
Now, Open up manager node and confirm what task are running:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
b68d99cad3da wordpress:latest "docker-entrypoint..." 5 minutes ago Up 4 minu
tes 80/tcp wordpressapp.2.8rybe5m4urikqsqje6hcpou9t
657cff3e37d5 wordpress:latest "docker-entrypoint..." 5 minutes ago Up 4 minu
tes 80/tcp wordpressapp.4.4avyixggcb8neej1h395ognt2
e71c164c36b3 mysql:latest "docker-entrypoint..." 10 minutes ago Up 10 min
utes 3306/tcp wordpressdb.1.puoe9lvfkciavkrzrkbrhrl6e
As we notice, there are 2 instances of wordpressapp task(container) running on the manager node(shown above) and 1 instance of wordpressdb.
Let’s pick up the wordpressdb task running on the manager node and try to reach out to wordpressapp running on the remote worker node. Because the container is missing the ping
command we need to install it first:
docker exec -it e71 bash -c "apt update && apt -y install iputils-ping"
Once installed, we can ping wordpressapp as shown below:
docker exec -it e71 ping wordpressapp
This should work successfully and be able to ping the wordpressapp as service name.
PING wordpressapp (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: icmp_seq=0 ttl=64 time=0.052 ms
^C--- wordpressapp ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.052/0.052/0.052/0.000 ms
Let us try to reach out to remote wordpressapp container from one of the wordpressdb instance running on the worker node by its hostname:
docker exec -it e71 ping wordpressapp.3.scia4v5i1znj378gujluad2ku
Output:
PING wordpressapp.3.scia4v5i1znj378gujluad2ku (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=6.175 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=0.131 ms
^C--- wordpressapp.3.scia4v5i1znj378gujluad2ku ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.131/3.153/6.175/3.022 ms
Voila ! We are able to ping wordpressapp service from container(running wordpresdb task) using the service name.Also, we were successful in reaching out to remote wordpressapp container using its hostname from one of wordpressdb container running in maanager node.
What features are available under Docker Swarm Mode:
- Service Discovery
- Routing Mesh
- Load Balancing
- Orchestration
- All of the above