杰瑞科技汇

如何用Python实现Keepalived高可用?

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

如何用Python实现Keepalived高可用?-图1
(图片来源网络,侵删)

We'll cover three main ways to integrate Python with Keepalived, from the simplest to the most advanced:

  1. Using Python Scripts as Health Checks: The most common use case. Running a custom Python script to check if a service is truly "healthy."
  2. Using Python to Generate Keepalived Configuration: Dynamically creating Keepalived's config file based on external data (like a database or API).
  3. 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.).
  • keepalived installed: sudo apt-get install keepalived or sudo yum install keepalived.
  • Python 3 installed: sudo apt-get install python3 or sudo 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.

如何用Python实现Keepalived高可用?-图2
(图片来源网络,侵删)
  • 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:

  1. Makes an HTTP GET request to /health.
  2. Checks if the response status code is 200.
  3. Checks if the response body contains "OK".
  4. Returns 0 if all checks pass, 1 otherwise.

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

  1. A Python script (perhaps run by a scheduler like cron or a management tool like Ansible/Terraform) determines the desired state of your cluster.
  2. This script generates the complete /etc/keepalived/keepalived.conf file.
  3. The script then sends a signal to the keepalived process 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, or pm2. 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 have keepalived running 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.

分享:
扫描分享到社交APP
上一篇
下一篇