🐋 Docker Swarm? Why Not K8s?
Docker Swarm is simple. It comes with Docker and has exactly what we need for this project...
We want to create a simple 5-service web application.
In order to understand why we’re using Docker instead of K8s here, we really need to ask ourselves what we really want out of a container orchestrator.
In other words, what do we need?
Similar to Maslow’s Hierarchy of Needs in an interesting way
Our Needs
- Orchestrator to relaunch a container if the container goes down
- Light load balancer between two nodes for our voting app
- Persistent storage
- Frontend/backend network
Goal, Success Criteria, & Prereqs
Argentina won the FIFA World Cup on 12/18
💻Prerequisites
- Linux, MacOS, WSL
- Terminal Access
- Internet Access
- Docker Engine + CLI installed
- Ability to create Swarm cluster
🥅Goal
The goal for this project is to create a 5-service web app that’s distributed amongst 5 nodes.
✅Success Criteria
Success is determined when the following is achieved.
- Visitors can visit the IP address of the website successfully and can:
- View webpage
- Interact with web app, cast, and change vote
- Administrator can view results in real-time
🗺️Directions
- All images are on Docker Hub, so you should use editor to craft your commands locally, then paste them into swarm shell (at least that's how I'd do it)
- a
backend
andfrontend
overlay network are needed. Nothing different about them other than that backend will help protect database from the voting web app. (similar to how a VLAN setup might be in traditional architecture) - The database server should use a named volume for preserving data.
Use the new
-mount
format to do this:-mount type=volume,source=db-data,target=/var/lib/postgresql/data
Services (names below should be service names)
- vote
- bretfisher/examplevotingapp_vote
- web frontend for users to vote dog/cat
- ideally published on TCP 80. Container listens on 80
- on frontend network
- 2+ replicas of this container
- redis
- redis:3.2
- key-value storage for incoming votes
- no public ports
- on frontend network
- 1 replica NOTE VIDEO SAYS TWO BUT ONLY ONE NEEDED
- worker
- bretfisher/examplevotingapp_worker
- backend processor of redis and storing results in postgres
- no public ports
- on frontend and backend networks
- 1 replica
- db
- postgres:9.4
- one named volume needed, pointing to /var/lib/postgresql/data
- on backend network
- 1 replica
- remember set env for password-less connections -e POSTGRES_HOST_AUTH_METHOD=trust
-
result
- bretfisher/examplevotingapp_result
- web app that shows results
- runs on high port since just for admins (lets imagine)
- so run on a high port of your choosing (I choose 5001), container listens on 80
- on backend network
- 1 replica
1️⃣ Create a 3 Node Swarm Cluster
Because this is not a tutorial on how to create a Swarm cluster, I will not be covering how to create one here. To do so, please follow the link located within the prerequisites or by clicking the link here. You will have to complete steps 1 - 5.
A successful 3-node cluster looks like this after typing docker node ls
.
2️⃣ Crafting the Docker Commands
There will be two parts to this step. The first will involve creating the frontend and backend overlay networks. These allow the nodes to connect and communicate with each other, and most importantly, load balance once traffic hits the node.
There will be a total of five Docker commands when it comes to our services. I will write each one, then explain what each part means.
Be warned, this step is dense!
⚡Part 1 - The Networks
Create Two Overlay Networks
docker network create \
--driver overlay \
frontend
&& docker network create \
--driver overlay \
backend
Commands Broken Down
docker network create
- Create a new network
--driver overlay
- Specifically create an overlay network
frontend
or backend
- The name of our network(s)
🧑🔧Part 2 - The Services
Create the Vote Webapp Frontend
docker service create \
--name vote-app \
-p 80:80 \
--network frontend \
--replicas 2 \
bretfisher/examplevotingapp_vote
Commands Broken Down
docker service create
- Create a new service for Swarm
--name vote-app
- Name the service *****vote-app*****
-p 80:80
- Publish & expose port 80 for outgoing/incoming traffic
--network frontend
- Attach the service to the frontend network
--replicas 2
- Create 2 replicas within the Swarm
bretfisher/examplevotingapp_vote
- The web app container image
Create the Database
Create a password using a secret. This is the most secure way of passing a password to the database. The only thing you need to do is clear your terminal log with history -c
after creating your password!
printf "enter-pass-here" | docker secret create db_pass -
printf "enter-pass-here"
- Create the password string that will be used
docker secret create
- Create a secret in docker
my_secret_data
- The name of the secret
-
- Copies enter-pass-here
into my_secret_data
docker service create \
--name db \
--network backend \
--secret my_secret_data \
-e POSTGRES_PASSWORD_FILE=/run/secrets/my_secret_data \
-e POSTGRES_HOST_AUTH_METHOD=trust \
--mount type=volume,source=db-data,target=/var/lib/postgresql/data \
postgres:9.4
Commands Broken Down
--secret my_secret_data
- Use the secret my_secret_data
-e POSTGRES_PASSWORD_FILE=/run/secrets/db_pass
- Tell postgres to use the secret, my_secret_data
-e POSTGRES_HOST_AUTH_METHOD=trust
- Allows all users to connect
--mount type=volume,source=db-data,target=/var/lib/postgresql/data
- Stores the data persistently in case the DB container gets restarted
Create the redis Service
docker service create --name redis --network frontend --replicas 1 redis:3.2
Create the Worker
docker service create --name worker --network frontend --network backend --replicas 1 bretfisher/examplevotingapp_worker
Create Results
docker service create --name result --network backend --replicas 1 -p 5001:80 bretfisher/examplevotingapp_result
3️⃣ Test It Out!
Head over to the IPv4 address from your instance and you should see something similar to this.
After casting the vote, head to the IP address for your server and specifically head to port 5001. You’ll be brought to a webpage where you can see the percentage between cats and dogs to see which is truly man’s best friend!
🏁Result
You’ve now got a fully operational, 5-service webapp running on three different nodes! This was a joy to complete as it was the most complicated of the projects I’ve done so far.
The original lesson had me use a static plaintext password for postgress but I had recently learned how to use secrets and wanted to give it a shot! It took me a few extra tries to figure out how to get it to work, but I’m glad I took the extra time to figure it out.
This was my last Docker Swarm project for the near-future. I will be moving on to learn Kubernetes now and I’m very excited for that!
Top comments (0)