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