Skip to content

DirkTheDaring/ansible-loadbalancer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Load Balancer — Ansible Playbook

This repository contains an Ansible playbook that provisions a highly-available load balancer for a Kubernetes control plane (or any TCP service) using HAProxy and Keepalived. The setup provides a virtual IP (VIP) managed via VRRP and forwards traffic (default: TCP 6443) to one or more backend API servers.

Tested layouts in the inventory show a typical Kubernetes API setup where HAProxy fronts multiple control-plane nodes on port 6443, and Keepalived advertises a shared VIP on the selected interface.


What it does

  • Installs and configures HAProxy with a TCP frontend and multiple backends.
  • Installs and configures Keepalived for VRRP to provide a floating Virtual IP (VIP) between two or more load balancer nodes.
  • Optionally hardens the system by disabling unneeded services and priming a package cache.
  • Uses group/host vars in the inventory*.yaml to control ports, VIP, interface, and HAProxy backends.

Repository layout (important bits)

playbook.yml                 # Entry playbook: disable_services, package_cache, haproxy, keepalived
inventory.yaml               # Example inventory (RHEL/Debian style IPs & vars)
roles/
  haproxy/
    defaults/main.yml        # Defaults (mode, options, template vars)
    tasks/main.yml           # Installs and enables haproxy, renders config
    templates/haproxy.cfg.j2 # HAProxy configuration template
  keepalived/
    defaults/main.yml        # Keepalived defaults (state, priority, interface, VIP, VRID, auth)
    tasks/main.yml           # Installs and enables keepalived, renders config
    templates/keepalived.conf.j2
  disable_services/
    defaults/main.yml        # List of unwanted services (per OS family)
    tasks/main.yml           # Stops & disables them
  package_cache/             # (If present) Preps package cache / mirrors
run.sh,                      # Convenience wrapper for Ansible execution
lint.sh                      # Ansible lint helper

Note: Exact role contents may vary slightly; see the files in roles/ for the authoritative configuration knobs.


Requirements

  • Control machine: Python 3 and Ansible >= 2.14 (recommended).
  • Managed hosts: Two or more Linux servers (e.g., Ubuntu/Debian/RHEL) with:
    • SSH access for an Ansible user with become: true (sudo) privileges.
    • Network interface name for the VIP (e.g., eth0, enp1s0).
  • Open firewall for:
    • VRRP traffic (protocol 112) between load balancer nodes.
    • VIP frontend port (default 6443) from clients to the load balancer VIP.
    • Backend node ports (e.g., control plane nodes on 6443).

Quick start

  1. Edit inventory:

    • inventory.yaml

    Key variables per host (examples taken from inventory.yaml):

    all:
      children:
        loadbalancers:
          hosts:
            192.168.195.10:
              keepalived_state: MASTER           # MASTER or BACKUP
              keepalived_priority: 101           # Higher on MASTER
              keepalived_interface: eth0         # Interface to bind VIP
              keepalived_virtual_ip: 192.168.222.2/17
              keepalived_virtual_router_id: 51   # Same across the VRRP group
    
              haproxy_frontend_bind: "*:6443"
              haproxy_frontend_options:
                - "option tcplog"
    
              haproxy_backend_name: talos-prod1-apiserver
              haproxy_backend_mode: "tcp"
              haproxy_backend_balance: "leastconn"
              haproxy_backend_options:
                - "option tcp-check"
    
              haproxy_backend_servers:
                - name: talos-prod1-apiserver-0
                  ip: 192.168.178.245
                  port: 6443
                  params: "check check-ssl verify none"
                # add more servers as needed

    Adjust keepalived_* variables to match your network. Ensure all nodes in the VRRP group use the same keepalived_virtual_router_id, keepalived_virtual_ip, and keepalived_auth_pass (if used).

  2. Run the playbook from the repo root:

    ansible-playbook -i inventory.yaml playbook.yml
  3. (Optional) Use helper scripts:

    ./run.sh           # wrapper around ansible-playbook

Variables (quick reference)

Keepalived (VRRP)

Defined in roles/keepalived/defaults/main.yml and/or per-host in inventory:

  • keepalived_state: MASTER | BACKUP
  • keepalived_priority: integer; higher = preferred master (e.g., MASTER=101, BACKUP=100)
  • keepalived_interface: interface name (e.g., eth0)
  • keepalived_virtual_router_id: 1..255; must match on all nodes
  • keepalived_virtual_ip: CIDR VIP (e.g., 192.168.1.100/24)
  • keepalived_auth_pass: shared password (if using auth)

HAProxy

Common vars (from inventory and role defaults):

  • haproxy_frontend_bind: e.g., "*:6443"
  • haproxy_frontend_mode: "tcp" (default for k8s API)
  • haproxy_frontend_options: list of strings (e.g., "option tcplog")
  • haproxy_backend_name: name for the backend (e.g., talos-prod1-apiserver)
  • haproxy_backend_mode: "tcp"
  • haproxy_backend_balance: e.g., "roundrobin", "leastconn"
  • haproxy_backend_options: list (e.g., "option tcp-check")
  • haproxy_backend_servers: list of backends
    - name: apiserver-0
      ip: 10.0.0.10
      port: 6443
      params: "check check-ssl verify none"

Service locations & lifecycle

  • HAProxy
    • Config: /etc/haproxy/haproxy.cfg (rendered from roles/haproxy/templates/haproxy.cfg.j2)
    • Service: systemctl status haproxy
  • Keepalived
    • Config: /etc/keepalived/keepalived.conf (rendered from roles/keepalived/templates/keepalived.conf.j2)
    • Service: systemctl status keepalived
  • VIP
    • Check VIP on the interface: ip addr show dev <iface>

Verification

After the playbook completes on all load balancer nodes:

# On any LB node:
sudo systemctl status haproxy keepalived

# VIP should be present on MASTER:
ip addr show dev <iface> | grep <VIP>

# From a client machine:
nc -vz <VIP> 6443
# or
openssl s_client -connect <VIP>:6443 -servername kubernetes  </dev/null
# Kubernetes API (if used):
curl -k https://<VIP>:6443/healthz

If you configured multiple backends, stopping one backend should not disrupt access via the VIP.


Hardening / housekeeping

The role disable_services stops and disables a predefined list of non-essential services (depends on OS). Review and modify the list in roles/disable_services/defaults/main.yml before running in production environments.


Notes & troubleshooting

  • Ensure L2 connectivity and VRRP (protocol 112) is allowed between the load balancer nodes.
  • All nodes in one VRRP group must share: keepalived_virtual_router_id, keepalived_virtual_ip, and authentication settings.
  • Firewalls must allow the VIP port to reach HAProxy and allow HAProxy to reach each backend server port.
  • If the interface name differs (e.g., enp1s0 vs eth0), set keepalived_interface accordingly in the inventory.

License

If you plan to open-source this, add a LICENSE file. No license file was detected in this archive.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors