Skip to main content

Docker Swarm Configuration for InkBlink

Requirements

Tailscale Download (MAC/PC) Download | Tailscale
Docker Swarm (PC) Windows | Docker Docs

Initializing Docker Swarm for Inkblink

All machines that run Inkblink must be in the same Tailscale network.

WINDOWS : If docker swarm cannot be initialized using the Tailscale IP address, run a separate Tailscale image using docker. See Run Tailscale Using Docker

# Print Tailscale IP
tailscale ip -4
# if running Tailscale on a separate image
# When Tailscale is running:
docker exec -it <tailscale-container-name> tailscale ip -4

Once you have found out what the Tailscale IP address for your machine is, initialize a docker swarm using that address

# Initialize Docker Swarm
docker swarm init --advertise-addr <YOUR_TAILSCALE_IP> --listen-addr 0.0.0.0:2377

A swarm has been initialized. For other nodes to join the swarm, each node must copy and paste the swarm token in their respective terminals. The token can be retrieved by the manager of the swarm using :

# The swarm manager can view nodes and assign nodes tasks
docker swarm join-token worker|manager

Expected Output:

$ docker swarm join-token worker
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-0xuent3dqa4feid2p8tfmtbncsbr7idxq1g682jdiiq9bi71ex3-boafyko6qug1khac6mi38uc17 <YOUR_TAILSCALE_IP>

 

 

 

 

Docker Swarm + Tailscale

Due to conflicts between docker swarm initializing a custom network as the listening address, a tailscale image will run in a container to provide access to host as a proxy.

Steps to Initialize Tailscale Proxy (One machine in swarm cluster)
docker compose -f tailscale-compose.yaml up -d
#IPv4 Address of Container Running Tailscale (not local machine ip)
#Use this IP to initialize Docker Swarm
docker exec tailscale-proxy tailscale ip -4

To verify docker swarm has been initiated, check if port 2377 is listening

 netstat -an | grep 2377

Expected Terminal Output

$ netstat -an | grep 2377
  TCP    [::1]:2377             [::]:0                 LISTENING
Initialize Docker Swarm
#$DOCKER_IP is the result of docker exec tailscale-proxy tailscale ip -4
docker swarm init --advertise-addr "$DOCKER_IP" --listen-addr 0.0.0.0:2377


Join Docker Swarm as Manager
docker swarm join --token SWMTKN-1-59rogaer609u1iaqugvorkz12bunzew6tqanvg7ufspfrw0s85-6x9qkhzat0artan0olngl3o2c 100.79.134.37:2377
Join Docker Swarm as Worker**
docker swarm join --token SWMTKN-1-1hpmu6wmnmodlfgyz7c43x0803cyj2wj77vx49nipeo5machk1-6yqgneioaiku3wz4whelm91gj 100.79.134.37:2377

You can verify the nodes that have joined the initialized swarm using :

# Only Manager Nodes can run this command
docker node ls

Expected Terminal Output

ID                            HOSTNAME         STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
nr29nq3n9jee55zz0h43r6kxd *   docker-desktop   Ready     Active         Leader           27.5.1
nz59idgmk5grpkk9eepg42glo     docker-desktop   Ready     Active                          28.0.1

The ID column will be important in designating which node will run which service.

Deploying the Distributed System

docker stack deploy -c compose.yaml inkblink

6 services in total run in this container (for two nodes):

Service Name

Node Label

Kafka

main_services
Coordinator main_services
Primary primary
Backup 1 primary
Backup 2 primary
Backup 3 primary
# Designate Node Label to Node_ID
docker node ls # <-- To list NODE_IDs
docker node update --label-add role=main_services <NODE_ID> # <-- Designate Node Label to Node


services:
  tailscale-proxy:
    container_name: tailscale-proxy
    image: tailscale/tailscale
    network_mode: "host"
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - TS_AUTHKEY=;
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_EXTRA_ARGS=--hostname=${HOSTNAME:-proxy-node}
    volumes:
      - tailscale-state:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun    
    restart: unless-stopped
    command: tailscaled

volumes:
  tailscale-state:
export $(grep -v '^#' .env | xargs)
envsubst < compose.yaml | docker stack deploy -c - inkblink