HA Docker Swarm Setup for Load Balancing with Keepalived + Traefik

1. Prerequisites
- 3+ nodes (1 manager minimum, but 3 recommended for HA)
- Static IP addresses for nodes
- Domain name pointing to your VIP (e.g., traefik.yourdomain.com)
2. Install Keepalived & Docker
2.1. On All Manager Nodes
# Ubuntu/Debian
sudo apt update && sudo apt install -y keepalived docker.io
# CentOS/RHEL
sudo yum install -y keepalived docker-ce
sudo systemctl enable --now docker
2.2. Enable Non-Local VIP Binding
Add to /etc/sysctl.conf:
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
3. Configure Keepalived VIP
3.1. Master Node
(/etc/keepalived/keepalived.conf)
vrrp_instance VI_1 {
state MASTER
interface ens192 # Your network interface virtual_router_id 51 priority 255
advert_int 1
authentication {
auth_type PASS
auth_pass your_secure_password }
virtual_ipaddress { 192.168.0.99/24 # Shared VIP }
track_script {
chk_traefik
}
}
vrrp_script chk_traefik {
script "/etc/keepalived/healthcheck.sh"
interval 2
weight 50
}
3.2. Backup Nodes
Use the same config but with:
state BACKUP
priority 254 # Lower priority for backups
4. Health Check Script
Create /etc/keepalived/healthcheck.sh (ensure Traefik is running):
#!/bin/bash
if curl -s http://127.0.0.1:8080/ping | grep -q "OK"; then
exit 0
else
exit 1
fi
Make executable:
sudo chmod +x /etc/keepalived/healthcheck.sh
5. Deploy Traefik with Docker Swarm
5.1. Create Overlay Network
docker network create --driver=overlay traefik-public
5.2. Deploy Traefik Stack (traefik-stack.yml) version: "3.9"
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=admin@yourdomain.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpChallenge.entrypoint=web"
deploy:
placement:
constraints:
- node.role == manager replicas: 1
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "traefik-certificates:/letsencrypt"
networks:
- traefik-public
volumes:
traefik-certificates:
networks:
traefik-public:
external: true
5.3. Deploy the Stack docker stack deploy -c traefik-stack.yml traefik
6. Configure Services for Traefik Routing
6.1. Example Service (web-stack.yml)
version: "3.9"
services:
web:
image: nginx:alpine
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`app.yourdomain.com`)"
- "traefik.http.routers.web.entrypoints=websecure"
- "traefik.http.routers.web.tls.certresolver=letsencrypt"
networks:
- traefik-public
networks:
traefik-public:
external: true
7. Verify Setup
7.1. Check Traefik Dashboard
Access via VIP: http://192.168.0.99:8080
7.2. Test HTTPS Routing
curl https://app.yourdomain.com
|