Search code examples
dockerdocker-composedockerfiledocker-swarmdocker-ingress

Reach available Docker Swarm hosts in a LAN when another host is down


I have a stack containing 3 services (backend, frontend, nginx). I have deployed this stack on Docker Swarm on 3 different hosts in the Same network (LAN) (3 different PCs).

Let's Suppose these Hosts have IP addresses of

192.168.1.13
192.168.1.55
192.168.8

I have my router set to forward all requests at port 80 to 80 of 192.168.1.13 and the same for 443 --> 443.

All three nodes are Managers. The problem arises when 192.168.1.13 is down. Then although all services migrate to the other 2 hosts 192.168.1.55 and 192.168.8 my router still forwards all my requests to 192.168.1.13 and thus someone cannot access my app. If I change the Router config to forward the requests to any other available host then the app is working.

My question is:

Is there a way to configure my router to forward my requests to a Virtual IP standing on Top of all my hosts? Is there another way I can solve my problem? I thought about Keepalived to transfer the IP of the down host to another that is up but i don't like this solution and I am afraid it will have a conflict with the Static IP Binding I have done in my router settings (I have binded each host's MAC address to a specific IP e.g 192.168.1.13 etc.). I have read about HAProxy but besides being unsure whether it will solve my issue, ideally I wouldn't want add an extra service if I can somehow use the docker swarm built in load balancer. Can somehow the docker swarm ingress network save my life?

My stack docker-compose file is as follow:

version: '3.8'

services:
  frontend:
    image: mydocker_hub/frontend
    deploy:
        replicas: 4
    ports:
      - "3001:3000"

  backend:
    image: mydocker_hub/backend
    deploy:
        replicas: 4
    ports:
      - "8001:8080"

  nginx:
    image: mydocker_hub/nginx
    deploy:
        mode: global
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - frontend
      - backend

Thanks in advance and I hope I explained my issue clear enough.

PS: I know that depends_on is being ignored in a stack deploy but I forgot to remove it.


Solution

  • Ok, I solved it using Keepalived.

    I made 3 config files as following and placed each on /etc/keepalived/keepalived.conf on my 3 hosts:

    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         [email protected]
       }
       notification_email_from user@host
       smtp_server localhost
       smtp_connect_timeout 30
    }
    
    ! state BACKUP for slaves
    ! priority 100 for slaves
    ! Replace interface with an existing interface
    vrrp_instance VI_1 {
        state MASTER
        interface eth0
        virtual_router_id 101
        priority 101
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.1.100
        }
    }
    

    Then I pointed my router to 192.168.1.100 (the virtual IP I created) and everything works as expected.