Skip to content

Install Keepalived

Keepalived

Keepalived enables us to use a single, shared virtual IP to access our service on Docker Swarm. This eliminates the need to target individual nodes and instead allows us to target one virtual IP that is self-healing and highly available. By doing so, we no longer require an external load balancer.

Our layout:

  • Node1 - 10.42.0.50
  • Node2 - 10.42.0.51
  • Node3 - 10.42.0.52
  • Ingress (virtual IP - Keepalived) - 10.42.1.53

Install Keepalived

On every node:

sudo apt-get -y install keepalived

On master node (swnode1) create file /etc/keepalived/keepalived.conf

global_defs {
  router_id DOCKER_INGRESS

  max_auto_priority       99
  vrrp_rt_priority        99
  checker_rt_priority     99
  vrrp_no_swap
  checker_no_swap
}

vrrp_instance VI_1 {
  state MASTER
  interface ens18
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass mypasswd
  }
  virtual_ipaddress {
  10.42.1.53
  }
}

Keepalived configuration file consists of various parameters that define how the virtual IP address should be managed and maintained in a high availability environment. Some of the common parameters in Keepalived's configuration file include:

  • router_id: is a unique identifier for the keepalived instance. The identifier is used by keepalived to differentiate between multiple instances of the service running on the same system. The value of the router_id can be any string that is unique to the keepalived instance.
  • vrrp_instance: defines the virtual router instance that will manage the virtual IP address.
  • interface: specifies the network interface that will be used to manage the virtual IP address.
  • state: defines the initial state of the virtual IP address, which can be either MASTER or BACKUP.
  • virtual_router_id: a unique identifier for the virtual router instance.
  • priority: defines the priority of the node to take over the virtual IP address. A higher value indicates a higher priority.
  • virtual_ipaddress: lists the virtual IP addresses that should be assigned to the node with the highest priority.
  • advert_in: refers to the advertisement interval. It specifies the frequency in seconds at which a keepalived Instance sends gratuitous ARP announcements to update its local ARP cache table on the network.
  • auth_pass: is the authentication password used between the keepalived instances running on different nodes. It is used to prevent unauthorized access to the keepalived service, and to ensure that only authorized keepalived instances can modify the virtual IP configuration.

On Node2 same file /etc/keepalived/keepalived.conf

global_defs {
  router_id DOCKER_INGRESS

  max_auto_priority       99
  vrrp_rt_priority        99
  checker_rt_priority     99
  vrrp_no_swap
  checker_no_swap
}

vrrp_instance VI_1 {
  state BACKUP
  interface ens18
  virtual_router_id 51
  priority 90
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass mypasswd
  }
  virtual_ipaddress {
    10.42.1.53
  }
}

We only changed two things:

  • state to BACKUP
  • priority to 90 from 100

Please Note

To configure nodes 3, you'll need to make a similar configuration as the node 2. But decrease the priority of each node by 10. For example, node 3 would have a priority of 80.

Start and enabled the service to start at boot on every node (start from Node 1)

sudo systemctl start keepalived
sudo systemctl enable keepalive

Check

To check if keepalived successfully negotiated the virtual IP, you can use the ip a command to list the IP addresses assigned to the network interfaces. The virtual IP should be listed under the interface specified in the interface directive in keepalived.conf and the state should be "MASTER" on the node with the highest priority, and "BACKUP" on the other nodes. You can also check the logs in the /var/log/syslog or /var/log/messages for any error messages related to keepalived.

nimda@swnode1:~$ ip a show ens18
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether bc:24:11:c6:1b:b9 brd ff:ff:ff:ff:ff:ff
    altname enp0s18
    inet 10.42.1.50/24 brd 10.42.1.255 scope global ens18
       valid_lft forever preferred_lft forever
    inet 10.42.1.53/32 scope global ens18
       valid_lft forever preferred_lft forever
    inet6 fdc2:e1f8:48af:8f47:be24:11ff:fec6:1bb9/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 1645sec preferred_lft 1645sec
    inet6 fe80::be24:11ff:fec6:1bb9/64 scope link 
       valid_lft forever preferred_lft forever

You can also try to ping the virtual IP from other nodes.

nimda@swnode2:~$ ping -c 3 10.42.1.53
PING 10.42.1.53 (10.42.1.53) 56(84) bytes of data.
64 bytes from 10.42.1.53: icmp_seq=1 ttl=64 time=0.266 ms
64 bytes from 10.42.1.53: icmp_seq=2 ttl=64 time=0.227 ms
64 bytes from 10.42.1.53: icmp_seq=3 ttl=64 time=0.354 ms

--- 10.42.1.53 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2064ms
rtt min/avg/max/mdev = 0.227/0.282/0.354/0.053 ms