Learn Keepalived - LVS Integration & Load Balancing
Episode 6 of 23

Learn Keepalived - LVS Integration & Load Balancing

This episode brings Keepalived into load balancing mode: configuring virtual_server with a scheduler and NAT, DR, or TUN mode, persistence rules for sticky connections, as well as per-real-server health checks and verification with ipvsadm.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Keepalived is not just a VIP failover engine; inside it lives the LVS subsystem that turns it into a pure L4 load balancer in the Linux kernel. Episode 6 unlocks the virtual_server mode: how a single VIP distributes traffic across many backends, which scheduler to use, and how persistence keeps sessions sticky.

In this episode you'll write a complete virtual_server configuration, choose the lb_kind that fits your topology, add per-real-server health checks, and verify the results with ipvsadm. This is the foundation of the HA load balancer frontend architecture promised in episode 1.

Anatomy of virtual_server

Basic Block

The virtual_server block connects a VIP with a set of real servers:

Basic virtual_server
virtual_server 192.168.1.100 80 {
  delay_loop 6
  lb_algo rr
  lb_kind DR
  protocol TCP
  persistence_timeout 50
  real_server 10.0.0.11 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 10.0.0.12 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 3
    }
  }
}
  • delay_loop: the backend check interval in seconds.
  • lb_algo: the connection scheduling algorithm.
  • lb_kind: the LVS mode, NAT, DR, or TUN.
  • protocol: TCP or UDP.
  • persistence_timeout: the sticky session duration in seconds.

The virtual_server 192.168.1.100 80 block wraps two real_servers, each with a TCP_CHECK health check that ensures port 80 is actually open before receiving traffic.

Choosing lb_algo

The scheduler choice determines the connection distribution pattern:

  • rr: round robin, even for homogeneous backends.
  • wrr: weighted round robin, splits according to weight.
  • lc: least connections, to the backend with the fewest connections.
  • wlc: weighted least connections, a combination of weight and load.
  • sh: source hashing, backend chosen from a hash of the client address.
  • dh: destination hashing, suitable for caches and proxies.

For most simple HTTP workloads, rr or wrr is enough. lc and wlc are fairer when connection durations vary widely.

Choosing lb_kind: NAT, DR, and TUN

  • NAT: the load balancer rewrites both source and destination addresses. Simple, but all replies must flow back through the load balancer, so it can become a bottleneck.
  • DR (direct routing): only requests pass through the load balancer; replies are sent directly from the backend. Backends must have the VIP on their loopback interface.
  • TUN: uses IP-IP tunneling, suitable for backends across subnets.

Choose DR for high performance with backends on one L2; choose NAT when you want simplicity and low traffic volumes.

Health Checks for Backends

TCP_CHECK and HTTP_GET

LVS provides several health check types. For web services, HTTP_GET is more accurate than a plain port check:

HTTP_GET for backend
real_server 10.0.0.11 80 {
  weight 1
  HTTP_GET {
    url {
      path /healthz
      status_code 200
    }
    connect_timeout 3
    nb_get_retry 3
  }
}

The HTTP_GET block requests the /healthz path and only considers the backend healthy if the response is 200. nb_get_retry 3 retries before declaring the backend failed.

Verification with ipvsadm

Once the daemon is running, check the result in the kernel:

View IPVS table
sudo ipvsadm -L -n
sudo ipvsadm -L -n --stats

The ipvsadm -L -n output shows the VIP, real servers, and weight status. The --stats part shows the number of incoming and outgoing connections per backend, proof that traffic is actually being distributed.

Persistence and Sticky Sessions

persistence_timeout keeps connections from the same client going to the same backend within a given time window:

Source-based persistence
virtual_server 192.168.1.100 443 {
  delay_loop 6
  lb_algo wlc
  lb_kind DR
  protocol TCP
  persistence_timeout 600
  persistence_granularity 255.255.255.0
  real_server 10.0.0.11 443 {
    weight 2
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 10.0.0.12 443 {
    weight 1
    TCP_CHECK {
      connect_timeout 3
    }
  }
}

persistence_timeout 600 keeps sessions sticky for 10 minutes, and persistence_granularity groups clients by subnet so the hash is more stable. For applications that keep state in server sessions, this parameter matters.

Combining Failover and Load Balancing

Keepalived's strength is that these two modes coexist: vrrp_instance keeps the VIP alive, virtual_server distributes traffic. When one load balancer node dies, the VIP moves to the standby node along with its entire IPVS configuration, so clients see no disruption.

One file, two roles
vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  virtual_ipaddress {
    192.168.1.100/24 dev eth0
  }
}
 
virtual_server 192.168.1.100 80 {
  delay_loop 6
  lb_algo rr
  lb_kind DR
  protocol TCP
  real_server 10.0.0.11 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 10.0.0.12 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 3
    }
  }
}

The vrrp_instance VI_1 and virtual_server configuration in one file yields a single unit: VIP failover plus load balancing. Make sure virtual_server is only active on the node that is MASTER.

Closing

Key takeaways:

  • virtual_server combines a VIP and a set of real servers in one block.
  • lb_algo determines distribution; choose based on your workload pattern.
  • DR mode wins on performance, NAT wins on simplicity.
  • Backend health checks use TCP_CHECK or HTTP_GET per real server.
  • persistence_timeout keeps client sessions on the same backend.
  • ipvsadm -L -n is the verification window into the kernel's IPVS table.

In episode 7 next, we cover logging and troubleshooting — Keepalived log levels, syslog integration, techniques for debugging VRRP state changes and IP failover, as well as steps to resolve the most common failure modes.

Learn Keepalived - LVS Integration & Load Balancing | Learn Keepalived