Of course! Let's dive into using Python with Keepalived. This is a powerful combination for building highly available and automated systems.

We'll cover three main ways to integrate Python with Keepalived, from the simplest to the most advanced:
- Using Python Scripts as Health Checks: The most common use case. Running a custom Python script to check if a service is truly "healthy."
- Using Python to Generate Keepalived Configuration: Dynamically creating Keepalived's config file based on external data (like a database or API).
- Using Keepalived to Run a Python Application: A less common but interesting pattern where Keepalived manages a Python process.
Prerequisites
Before you start, ensure you have:
- A Linux system (like Ubuntu, CentOS, etc.).
keepalivedinstalled:sudo apt-get install keepalivedorsudo yum install keepalived.- Python 3 installed:
sudo apt-get install python3orsudo yum install python3.
Method 1: Using Python Scripts as Health Checks
This is the primary way to leverage Python's flexibility. Instead of a simple ping check, you can write a script that performs complex logic, such as checking a database connection, verifying a specific API endpoint, or parsing a log file.
The Concept
Keepalived can execute a script and check its exit code to determine the health of a service.

- Exit Code 0: The service is healthy. Keepalived will consider the check successful.
- Exit Code 1 (or any non-zero): The service is unhealthy. Keepalived will consider the check failed.
Example Scenario
We have a web application running on port 8080. A simple TCP port check isn't enough; we need to verify that the application is actually responding correctly. We'll write a Python script that:
- Makes an HTTP GET request to
/health. - Checks if the response status code is
200. - Checks if the response body contains
"OK". - Returns
0if all checks pass,1otherwise.
Step 1: Create the Python Health Check Script
Let's create a script named /usr/local/bin/check_app.py.
sudo nano /usr/local/bin/check_app.py
Paste the following code into the file:
#!/usr/bin/env python3
import requests
import sys
import os
# Configuration
# Use an environment variable for the URL to make it configurable
HEALTH_URL = os.getenv('HEALTH_URL', 'http://localhost:8080/health')
TIMEOUT = 5 # seconds
def check_health():
"""
Checks the health of the application by making an HTTP request.
Returns 0 for healthy, 1 for unhealthy.
"""
try:
response = requests.get(HEALTH_URL, timeout=TIMEOUT)
# Check for successful HTTP status code
if response.status_code != 200:
print(f"Health check failed: HTTP Status {response.status_code}")
return 1
# Check for expected content in the response body
if "OK" not in response.text:
print(f"Health check failed: Response body does not contain 'OK'")
return 1
print("Health check successful!")
return 0
except requests.exceptions.ConnectionError:
print("Health check failed: Connection Error. Is the service running?")
return 1
except requests.exceptions.Timeout:
print("Health check failed: Request timed out.")
return 1
except Exception as e:
print(f"Health check failed: An unexpected error occurred: {e}")
return 1
if __name__ == "__main__":
sys.exit(check_health())
Make the script executable:
sudo chmod +x /usr/local/bin/check_app.py
Step 2: Configure Keepalived to Use the Script
Now, edit the Keepalived configuration file, typically located at /etc/keepalived/keepalived.conf.
sudo nano /etc/keepalived/keepalived.conf
Here is an example configuration for a simple failover setup. We'll define a virtual_server and use our Python script as a check.
! /etc/keepalived/keepalived.conf
! Configuration File for keepalived
vrrp_script check_my_app {
# The script to run. Use the full path.
script "/usr/local/bin/check_app.py"
# The interval in seconds to run the script.
interval 5
# The number of failures needed to mark the service as down.
# Here, 2 consecutive failures will cause the failover.
fall 2
# The number of successes needed to mark the service as up again.
rise 1
# The timeout for the script to complete.
timeout 2
}
vrrp_instance VI_1 {
state BACKUP # MASTER on the primary, BACKUP on the secondary
interface eth0 # The network interface to use for VRRP
virtual_router_id 51 # Must be the same on all servers in the group
priority 100 # Higher number for the MASTER server
advert_int 1 # Advertisement interval in seconds
# Use the authentication to prevent rogue VRRP messages
authentication {
auth_type PASS
auth_pass mysecret
}
# The virtual IP address that will be floated
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:1
}
# Track the script we defined above. If the script fails,
# the priority will be decremented by the weight value.
track_script {
check_my_app
}
}
Step 3: Restart Keepalived
Apply the new configuration:
sudo systemctl restart keepalived
You can monitor the logs to see your script being executed:
tail -f /var/log/keepalived.log
You should see output like:
Health check successful! or Health check failed: Connection Error. Is the service running?.
Method 2: Using Python to Generate Keepalived Configuration
This is useful for orchestration. Imagine you have a cluster of servers, and you want to dynamically assign virtual IPs or priorities based on which servers are currently available.
The Concept
- A Python script (perhaps run by a scheduler like
cronor a management tool like Ansible/Terraform) determines the desired state of your cluster. - This script generates the complete
/etc/keepalived/keepalived.conffile. - The script then sends a signal to the
keepalivedprocess to reload its configuration, making the changes take effect without restarting the service.
Example Scenario
We have two servers, server1 and server2. We want server1 to be the master only if it's online. If it's offline, server2 should become the master. A central Python script will decide the master and generate the config for both servers.
Step 1: Create the Python Generator Script
This script will decide the master and generate the config file.
# generate_config.py
import os
import sys
# --- Configuration ---
SERVER_ID = os.getenv('SERVER_ID', 'unknown') # Set this as an env var when running
VIRTUAL_IP = "192.168.1.100"
INTERFACE = "eth0"
PRIORITY_MASTER = 100
PRIORITY_BACKUP = 90
CONFIG_PATH = "/etc/keepalived/keepalived.conf"
# --- Logic ---
# In a real scenario, you'd ping the other server or check a database
# For this example, we'll hardcode the master.
# Let's assume server1 is the designated master.
if SERVER_ID == "server1":
state = "MASTER"
priority = PRIORITY_MASTER
else:
state = "BACKUP"
priority = PRIORITY_BACKUP
# --- Template ---
config_template = f"""! /etc/keepalived/keepalived.conf
! Generated by Python script
vrrp_instance VI_1 {{
state {state}
interface {INTERFACE}
virtual_router_id 51
priority {priority}
advert_int 1
authentication {{
auth_type PASS
auth_pass mysecret
}}
virtual_ipaddress {{
{VIRTUAL_IP}/24 dev {INTERFACE} label {INTERFACE}:1
}}
}}
"""
# --- Write and Reload ---
print(f"Generating config for {SERVER_ID} as {state} with priority {priority}...")
try:
with open(CONFIG_PATH, 'w') as f:
f.write(config_template)
print(f"Config written to {CONFIG_PATH}")
# Reload keepalived to apply the new config
# This is more graceful than a restart
os.system("systemctl reload keepalived")
print("Keepalived reloaded successfully.")
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
print("Configuration update complete.")
Step 2: Run the Script
You would run this script on each server in your cluster, setting the SERVER_ID environment variable.
On server1:
export SERVER_ID="server1" python3 generate_config.py
On server2:
export SERVER_ID="server2" python3 generate_config.py
This approach is the foundation for dynamic, auto-scaling infrastructure.
Method 3: Using Keepalived to Run a Python Application
This is an anti-pattern in most cases but can be useful in specific, simple scenarios. You are essentially using Keepalived as a process manager to restart a Python script if it crashes.
The Concept
Keepalived can be configured to monitor a process. If that process dies, Keepalived will try to restart it.
Example Scenario
You have a simple Python daemon that you want to keep running.
Step 1: Create the Python Daemon
# /usr/local/bin/my_daemon.py
import time
import sys
import os
print("Daemon started.", flush=True)
try:
while True:
# Do some work...
print(f"Daemon is alive at {time.ctime()}", flush=True)
time.sleep(10)
except KeyboardInterrupt:
print("Daemon stopped by user.", flush=True)
sys.exit(0)
except Exception as e:
print(f"Daemon crashed: {e}", flush=True)
sys.exit(1) # Exit with a non-zero code to signal failure
Make it executable: sudo chmod +x /usr/local/bin/my_daemon.py
Step 2: Configure Keepalived
! /etc/keepalived/keepalived.conf
vrrp_script my_daemon_monitor {
script "/usr/local/bin/my_daemon.py"
interval 2
timeout 10
fall 2
rise 1
}
# Note: We don't need a virtual_ipaddress for this simple monitor.
# Keepalived will just run the script and restart it if it fails.
When to Use This (and When Not To)
- Don't use this for complex, long-running applications. Use a proper process manager like
systemd,supervisord, orpm2. They are designed for this purpose and offer far more features (logging, environment variables, dependency management, etc.). - You might consider this for a very simple, self-contained script where you want to avoid adding another dependency like
systemd, and you already havekeepalivedrunning for other purposes (like VIP management).
Summary
| Method | Use Case | Pros | Cons |
|---|---|---|---|
| Python as Health Check | Complex service health validation (DB, API, custom logic). | Most Common & Recommended. Leverages Python's power for custom logic. | Adds a dependency on Python and its libraries (e.g., requests). |
| Python to Generate Config | Dynamic orchestration, auto-scaling, configuration management. | Highly flexible and powerful for automated infrastructure. | More complex to set up; requires careful logic to avoid conflicts. |
| Keepalived to Run Python App | Simple process restart for a basic, self-contained script. | Can be a quick fix if keepalived is already running. |
Not recommended. Outclassed by dedicated process managers. |
For almost all use cases, Method 1 is the correct and standard approach for integrating Python with Keepalived.
