Docker Swarm Single Node - CloudCommandos/JohnChan GitHub Wiki

Introduction

Docker Swarm is a container orchestrator that is native to Docker. The purpose of this guide is to test out the load-balancing feature of Docker Swarm for replicated containers. Without Docker Swarm, each container of the same service will need to be specifically configured with unique ports, and a load-balancer will be required to round-robin traffic among them.

Assumptions

  • You have one Ubuntu 18.04 node with IP 10.0.1.61/24

Install Docker

sudo apt update
sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

For x86_64 / amd64 systems, add docker package repository

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

Docker Swarm

Initialize your Docker node as a Docker Swarm manager

sudo docker swarm init --advertise-addr 10.0.1.61

Check that the swarm is formed (You should only have 1 node in this case)

sudo docker node ls

Create a project directory

mkdir -p /opt/dockerswarm/example
cd /opt/dockerswarm/example

Create a sample Docker Compose file docker-stack.yml

nano docker-stack.yml
version: "3.8"
services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=12345
      # Allow logins without password just for this demo
      - POSTGRES_HOST_AUTH_METHOD=trust
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        max_replicas_per_node: 1
        constraints:
          - "node.role==manager"

  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - "node.role==manager"

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints:
          - "node.role==manager"

networks:
  frontend:
  backend:

volumes:
  db-data:

This configuration is modified from Docker Compose's official website. Some options are not relevant to our setup but are retained to show you some available configurations. E.g. the placement constraint is not necessary for this guide since we only have one Docker Swarm node.

Deploy the Docker Stack

sudo docker stack deploy --compose-file docker-stack.yml your_stack_name

Open your browser and visit these urls:

# Voting page
http://localhost:5000

# Result page
http://localhost:5001

The Voting page is served by replicated containers. By Refreshing the page you can see the changing container ID on the page. The HTTP request is received by our Docker Swarm node at port 5000 and subsequently passed to a voting page container in round-robin fashion.