- UCP installed with at least 2 nodes joined
- Client bundle downloaded
- Go to https://github.com/docker/swarm-microservice-demo-v1 and read the page to get a high level understanding of the application we are going to run.
- Clone the application repository into a local folder on your machine.
- Remove all existing applications you have deployed on UCP.
-
Change directory to the Voting Application folder
-
Launch the application with Docker Compose. What can you observe?
johnny@JT MINGW64 ~/Documents/GitHub/swarm-microservice-demo-v1 (master) $ docker-compose up -d ... ... Creating swarmmicroservicedemov1_vote-worker_1 Creating swarmmicroservicedemov1_web-vote-app_1 unable to find a node that satisfies node==frontend01
-
Try and identify the cause of the error and edit the
docker-compose.yml
file to fix it.Let's take a quick look at the
docker-compose.yml
fileversion: '2' services: web-vote-app: build: web-vote-app environment: WEB_VOTE_NUMBER: "01" constraint:node: "=frontend01" vote-worker: build: vote-worker environment: FROM_REDIS_HOST: 1 TO_REDIS_HOST: 1 results-app: build: results-app redis01: image: redis:3 store: image: postgres:9.5 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=pg8675309
Notice the line saying
constraint:node: "=frontend01"
. This tells Docker that the service container must be run on a Node calledfrontend01
. We don't have such a Node and hence the error message.This Compose file was written with a development machine in mind as opposed to a production deployment. Hence why each service has a
build
instruction instead of animage
instruction.Delete the
constraint:node
line and save the file. -
Once the error has been fixed, launch the application again.
This time there shouldn't be any errors.
Note: Sometimes, you may run into the following type of error. This depends on the setup of your AWS VM and usually occurs on Linux kernel version 3.13 or below
409 Conflict: subnet sandbox join failed for "70.28.0.0/16": overlay subnet 10.0.0.0/16 has conflicts in the host while running in host mode
This is because Compose is trying to create an Overlay network on a subnet that is already being used by the host. This is due to the way AWS allocates addresses. If you run into this error, add the following configuration to the end of your
docker-compose.yml
file.networks: default: ipam: config: - subnet: 10.10.10.0/24
The error can also be resolved by upgrading the Linux Kernel to version 3.19 or later.
-
Check the application is up and running and that the containers are running across different nodes.
-
Check the Networks page and verify that a network called
swarmmicroservicedemov1_default
has been created.You should see that the network exists. The name is derived from the name of the project folder. The network should be using the
overlay
driver. This tells us that it is a multi host network.
Our docker-compose.yml
file didn't necessarily follow the best practices. Ideally you shouldn't build your images when deploying your application. The Compose
file should be running pre-built images from a registry. Remember, developers build the images and push them to the registry, while IT operations runs the images.
-
Delete the Voting Application from the Applications page in UCP.
-
Take a look at the Compose file at https://github.com/nicolaka/voteapp-base/blob/master/docker-compose.yml
Compare this to the Compose file in the Voting App repo. What do you notice as the difference?
-
Clone the Voteapp Base repository into a folder on your PC / Mac
$ git clone https://github.com/nicolaka/voteapp-base
-
Open the
docker-compose.yml
file in thevoteapp-base
folder and change the port mapping of thevoting-app
service. Map port 80 in the container to port 80 on the host.To do this, look for the section:
voting-app: image: docker/example-voting-app-voting-app ports: - "80"
Change it to
voting-app: image: docker/example-voting-app-voting-app ports: - "80:80"
The reason for this is so that as IT operations, we control which ports services are exposed on as opposed to having the port automatically mapped. Also, if we use automatic port mapping, Docker will choose a port that is most likely blocked by AWS, therefore preventing external access to our application.
-
Repeat the same procedure, for the
result-app
service. Map port 80 to port 5000 -
Launch the application
-
Verify that the application containers are scheduled on different nodes.
-
Check the Networks page and verify that an overlay network with the name
voteappbase_voteapp
was created.
-
Open the
voteappbase_voting-app_1
on your web browser. You should see the following:This is the web application where we can cast a vote. From our configuration, we know that the container is available through port 80 on the host. Therefore we need to find out what node the container is running on and point our browser to the URL of that node.
-
Cast your vote.
-
Open
voteappbase_result-app_1
on your web browser and see the results of your vote.You should see the following screen, albeit with a different percentage allocation depending on how you cast your vote.
Previously, when we ran the HelloRedis application, you may remember that both containers were scheduled onto the same node. The reason was because the Compose file in that application was in the V1 format and that we used container links to get our services talking with each other. When links are used, Swarm will schedule a container on the same node as the container it is linked to.
This was the docker-compose.prod.yml
file we used previously
javaclient:
image: trainingteam/hello-redis:1.0
links:
- redis:redisdb
redis:
image: redis
If we deleted the "links:" instruction on our javaclient
service, we could get Swarm / UCP to run the containers on different nodes. However,
the containers would be run on the default network and will not be able to communicate with each other using their service names. You would have to use
the Node IP and exposed ports, which is not ideal.
The best solution to get our HelloRedis
example working on multiple nodes is to convert the docker-compose.prod.yml
file to a V2
file.
-
Convert the
docker-compose.prod.yml
file to a Version 2 Compose file.Hint: The
redis
service name will need to be changed toredisdb
as thejavaclient
code uses this name to connect to theredis
service -
Run the HelloRedis application and verify that the containers are deployed on different nodes.