一、整体简介
1. 组合作用
- HAProxy:负载均衡 / 反向代理,转发流量、做四层 / 七层代理。
- Keepalived:实现主备故障转移(高可用),通过虚拟 IP (VIP) 漂移,一台故障自动切到另一台,避免单点故障。
2. 工作原理
(1)两台服务器:主节点 (Master)、备节点 (Backup)
(2)对外共用一个虚拟 IP (VIP),用户只访问 VIP
(3)Keepalived 互相心跳检测:
- 主节点正常:VIP 在主节点,流量走主 HAProxy
- 主节点宕机 / HAProxy 异常:VIP 自动漂移到备节点,业务无缝切换
(4)主节点恢复后,默认抢回 VIP(可配置不抢占)
二、HAProxy安装
bash
#!/bin/bash
# HAProxy 自动下载源码 + 编译安装脚本 (CentOS/Rocky/Ubuntu)
# ==================== 自定义配置项 ====================
HAPROXY_VERSION="3.4.0"
LUA_VERSION="5.5.0"
HAPROXY_FILE="haproxy-${HAPROXY_VERSION}.tar.gz"
LUA_FILE="lua-${LUA_VERSION}.tar.gz"
# 源码下载地址
HAPROXY_URL="https://www.haproxy.org/download/${HAPROXY_VERSION%.*}/src/${HAPROXY_FILE}"
LUA_URL="https://www.lua.org/ftp/${LUA_FILE}"
HAPROXY_INSTALL_DIR="/apps/haproxy"
SRC_DIR="/usr/local/src"
# 监控页面账号密码
STATS_USER="admin"
STATS_PASS="123456"
# 后端集群IP(按需修改)
VIP="192.168.10.100"
MASTER1="192.168.10.101"
MASTER2="192.168.10.102"
MASTER3="192.168.10.103"
# ======================================================
# 基础变量
CPUS=$(nproc)
LOCAL_IP=$(hostname -I | awk '{print $1}')
CWD=$(pwd)
. /etc/os-release
# 彩色输出函数
color() {
local msg="$1"
local ret="$2"
echo -n "$msg"
if [[ $ret -eq 0 ]]; then
echo -e "\033[60G[\033[1;32m OK \033[0m]"
else
echo -e "\033[60G[\033[1;31mFAILED\033[0m]"
fi
}
# 自动下载源码包
download_file() {
echo "开始下载 Lua 源码包..."
if [[ ! -f ${LUA_FILE} ]]; then
wget -q ${LUA_URL}
[[ $? -eq 0 ]] || { color "Lua 源码下载失败" 1; exit 1; }
fi
color "Lua 源码包准备完成" 0
echo "开始下载 HAProxy 源码包..."
if [[ ! -f ${HAPROXY_FILE} ]]; then
wget -q ${HAPROXY_URL}
[[ $? -eq 0 ]] || { color "HAProxy 源码下载失败" 1; exit 1; }
fi
color "HAProxy 源码包准备完成" 0
}
# 安装系统依赖
install_deps() {
if [[ ${ID} =~ centos|rocky ]]; then
yum -y install gcc make gcc-c++ pcre-devel openssl-devel systemd-devel libevent-devel readline-devel wget
elif [[ ${ID} == "ubuntu" ]]; then
apt update && apt -y install gcc make libssl-dev libpcre3-dev zlib1g-dev libreadline-dev libsystemd-dev wget
else
color "不支持当前系统: ${ID}" 1
exit 1
fi
[[ $? -eq 0 ]] || { color "依赖安装失败" 1; exit 1; }
color "系统依赖安装完成" 0
}
# 编译安装 Lua + HAProxy
compile_install() {
# 编译 Lua
tar -xf "${LUA_FILE}" -C "${SRC_DIR}"
LUA_DIR="${LUA_FILE%.tar*}"
cd "${SRC_DIR}/${LUA_DIR}" || exit 1
make all test
cd "${CWD}" || exit 1
# 编译 HAProxy
tar -xf "${HAPROXY_FILE}" -C "${SRC_DIR}"
HAPROXY_DIR="${HAPROXY_FILE%.tar*}"
cd "${SRC_DIR}/${HAPROXY_DIR}" || exit 1
make -j "${CPUS}" \
ARCH=x86_64 \
TARGET=linux-glibc \
USE_PCRE=1 \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_SYSTEMD=1 \
USE_CPU_AFFINITY=1 \
USE_LUA=1 \
LUA_INC="${SRC_DIR}/${LUA_DIR}/src" \
LUA_LIB="${SRC_DIR}/${LUA_DIR}/src" \
PREFIX="${HAPROXY_INSTALL_DIR}"
make install PREFIX="${HAPROXY_INSTALL_DIR}"
[[ $? -eq 0 ]] || { color "HAProxy 编译失败" 1; exit 1; }
color "HAProxy 编译安装成功" 0
# 创建软链接、目录
ln -sf "${HAPROXY_INSTALL_DIR}/sbin/haproxy" /usr/sbin/
mkdir -p /etc/haproxy /var/lib/haproxy
}
# 创建运行用户
create_user() {
groupadd -g 99 haproxy 2>/dev/null
useradd -u 99 -g haproxy -d /var/lib/haproxy -M -r -s /sbin/nologin haproxy 2>/dev/null
color "HAProxy 运行用户创建完成" 0
}
# 生成配置文件
create_config() {
cat > /etc/haproxy/haproxy.cfg <<EOF
global
maxconn 100000
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth ${STATS_USER}:${STATS_PASS}
#listen kubernetes-6443
# bind ${VIP}:6443
# mode tcp
# log global
# server ${MASTER1} ${MASTER1}:6443 check inter 3000 fall 2 rise 5
# server ${MASTER2} ${MASTER2}:6443 check inter 3000 fall 2 rise 5
# server ${MASTER3} ${MASTER3}:6443 check inter 3000 fall 2 rise 5
EOF
color "HAProxy 配置文件生成完成" 0
}
# 生成 Systemd 服务
create_service() {
cat > /lib/systemd/system/haproxy.service <<EOF
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 \$MAINPID
[Install]
WantedBy=multi-user.target
EOF
color "Systemd 服务文件生成完成" 0
}
# 启动服务
start_service() {
systemctl daemon-reload
systemctl enable --now haproxy
if systemctl is-active --quiet haproxy; then
color "HAProxy 服务启动成功" 0
echo -e "\n----------------------------------------"
echo "监控地址: http://${LOCAL_IP}:9999/haproxy-status"
echo "账号密码: ${STATS_USER} / ${STATS_PASS}"
echo "----------------------------------------"
else
color "HAProxy 服务启动失败" 1
exit 1
fi
}
# 主函数
main() {
install_deps
download_file
compile_install
create_user
create_config
create_service
start_service
}
main
三、Keepalived安装
bash
#!/bin/bash
# Keepalived 离线编译安装脚本 (区分主备节点 | CentOS/Rocky/Ubuntu)
# 使用示例:
# 主节点: ./install_keepalived.sh master
# 备节点: ./install_keepalived.sh backup
# ==================== 全局固定配置项 ====================
KEEPALIVED_VERSION="2.3.4"
KEEPALIVED_FILE="keepalived-${KEEPALIVED_VERSION}.tar.gz"
INSTALL_DIR="/apps/keepalived"
SRC_DIR="/usr/local/src"
# VRRP 通用配置(主备必须一致)
VIP="192.168.10.100"
VRRP_ID=51
VRRP_PASS="123456"
# 网卡名称(根据实际环境修改)
IFACE="eth0"
# 优先级配置
PRI_MASTER=100
PRI_BACKUP=80
# ======================================================
# 帮助信息
usage() {
echo "用法: $0 [ master | backup ]"
echo "示例:"
echo " $0 master # 部署为主节点"
echo " $0 backup # 部署为备节点"
exit 1
}
# 参数校验
if [[ $# -ne 1 ]]; then
echo "错误: 必须传入节点角色参数!"
usage
fi
NODE_TYPE="$1"
if [[ ${NODE_TYPE} != "master" && ${NODE_TYPE} != "backup" ]]; then
echo "错误: 参数仅支持 master / backup"
usage
fi
# 根据角色赋值
if [[ ${NODE_TYPE} == "master" ]]; then
NODE_ROLE="MASTER"
PRIORITY=${PRI_MASTER}
else
NODE_ROLE="BACKUP"
PRIORITY=${PRI_BACKUP}
fi
# 基础变量
CPUS=$(nproc)
LOCAL_IP=$(hostname -I | awk '{print $1}')
CWD=$(pwd)
. /etc/os-release
# 彩色输出函数
color() {
local msg="$1"
local ret="$2"
echo -n "$msg"
if [[ $ret -eq 0 ]]; then
echo -e "\033[60G[\033[1;32m OK \033[0m]"
else
echo -e "\033[60G[\033[1;31mFAILED\033[0m]"
fi
}
# 检查离线包是否存在
check_file() {
[[ -f ${KEEPALIVED_FILE} ]] || { color "缺失 ${KEEPALIVED_FILE}" 1; exit 1; }
color "离线安装包检查通过" 0
}
# 安装系统依赖
install_deps() {
if [[ ${ID} =~ centos|rocky ]]; then
yum -y install gcc make libnl-devel libnfnetlink-devel openssl-devel iproute
elif [[ ${ID} == "ubuntu" ]]; then
apt update && apt -y install gcc make libnl-3-dev libnl-genl-3-dev libssl-dev iproute2
else
color "不支持当前系统: ${ID}" 1
exit 1
fi
[[ $? -eq 0 ]] || { color "依赖安装失败" 1; exit 1; }
color "系统依赖安装完成" 0
}
# 编译安装 Keepalived
compile_install() {
# 解压源码
tar -xf "${KEEPALIVED_FILE}" -C "${SRC_DIR}"
KA_DIR="${KEEPALIVED_FILE%.tar*}"
cd "${SRC_DIR}/${KA_DIR}" || exit 1
# 编译配置
./configure --prefix="${INSTALL_DIR}" --enable-vrrp --enable-lvs
# 编译安装
make -j "${CPUS}"
make install
[[ $? -eq 0 ]] || { color "Keepalived 编译失败" 1; exit 1; }
color "Keepalived 编译安装成功" 0
# 全局软链接
ln -sf "${INSTALL_DIR}/sbin/keepalived" /usr/sbin/
ln -sf "${INSTALL_DIR}/sbin/keepalived" /usr/bin/
# 目录初始化
mkdir -p /etc/keepalived /var/run/keepalived
}
# 生成 HAProxy 健康检查脚本
create_check_script() {
local check_script="/etc/keepalived/check_haproxy.sh"
cat > "${check_script}" <<EOF
#!/bin/bash
if ! pidof haproxy &>/dev/null; then
systemctl stop keepalived
fi
EOF
chmod +x "${check_script}"
color "HAProxy 健康检查脚本生成完成" 0
}
# 生成主配置文件(自动区分主备)
create_config() {
local cfg="/etc/keepalived/keepalived.conf"
cat > "${cfg}" <<EOF
global_defs {
router_id ${NODE_ROLE}_${LOCAL_IP}
script_user root
enable_script_security
}
vrrp_script chk_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state ${NODE_ROLE}
interface ${IFACE}
virtual_router_id ${VRRP_ID}
priority ${PRIORITY}
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass ${VRRP_PASS}
}
virtual_ipaddress {
${VIP}/24 dev ${IFACE}
}
track_script {
chk_haproxy
}
}
EOF
color "Keepalived 主配置文件(${NODE_ROLE})生成完成" 0
}
# 生成 Systemd 服务文件
create_service() {
local service_file="/lib/systemd/system/keepalived.service"
cat > "${service_file}" <<EOF
[Unit]
Description=Keepalived High Availability
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/keepalived -D -f /etc/keepalived/keepalived.conf
ExecReload=/usr/sbin/keepalived -D -f /etc/keepalived/keepalived.conf --reload
ExecStop=/usr/bin/killall keepalived
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
color "Systemd 服务文件生成完成" 0
}
# 启动服务
start_service() {
systemctl daemon-reload
systemctl enable --now keepalived
if systemctl is-active --quiet keepalived; then
color "Keepalived 服务启动成功" 0
echo -e "\n----------------------------------------"
echo "虚拟VIP: ${VIP}"
echo "节点角色: ${NODE_ROLE}"
echo "优先级: ${PRIORITY}"
echo "绑定网卡: ${IFACE}"
echo "----------------------------------------"
else
color "Keepalived 服务启动失败" 1
exit 1
fi
}
# 主入口函数
main() {
check_file
install_deps
compile_install
create_check_script
create_config
create_service
start_service
}
# 执行主函数
main
注意:
1.提前下载对应版本源码包,和脚本放在同一目录
https://www.keepalived.org/software/keepalived-2.3.4.tar.gz
2.主节点执行:./install_keepalived.sh master
3.备节点执行:./install_keepalived.sh backup