2025-10-29 17:36:30 +08:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化变量
|
|
|
|
|
|
ACTION=""
|
|
|
|
|
|
VIP=""
|
|
|
|
|
|
PRIORITY=150
|
|
|
|
|
|
INTERFACE=""
|
|
|
|
|
|
KEEPALIVED_CONF="/etc/keepalived/keepalived.conf"
|
|
|
|
|
|
CHECK_SCRIPT="/usr/local/bin/check_haproxy.sh"
|
|
|
|
|
|
|
|
|
|
|
|
# 打印帮助信息
|
|
|
|
|
|
usage() {
|
|
|
|
|
|
echo "用法: $0 [操作] [选项]"
|
|
|
|
|
|
echo "操作:"
|
|
|
|
|
|
echo " --install 安装并配置keepalived"
|
|
|
|
|
|
echo " --uninstall 卸载keepalived并清理配置"
|
|
|
|
|
|
echo "安装选项:"
|
|
|
|
|
|
echo " --vip <VIP> 必选,虚拟IP(格式:192.168.1.100/24)"
|
|
|
|
|
|
echo " --priority <数值> 可选,优先级(默认150,主节点设高)"
|
|
|
|
|
|
echo "示例:"
|
|
|
|
|
|
echo " 安装主节点: $0 --install --vip 192.168.1.100/24 --priority 150"
|
|
|
|
|
|
echo " 安装备节点: $0 --install --vip 192.168.1.100/24 --priority 140"
|
|
|
|
|
|
echo " 卸载: $0 --uninstall"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 解析参数
|
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
|
case "$1" in
|
|
|
|
|
|
--install|--uninstall)
|
|
|
|
|
|
ACTION="$1"
|
|
|
|
|
|
shift
|
|
|
|
|
|
;;
|
|
|
|
|
|
--vip)
|
|
|
|
|
|
VIP="$2"
|
|
|
|
|
|
shift 2
|
|
|
|
|
|
;;
|
|
|
|
|
|
--priority)
|
|
|
|
|
|
PRIORITY="$2"
|
|
|
|
|
|
shift 2
|
|
|
|
|
|
;;
|
|
|
|
|
|
*)
|
|
|
|
|
|
echo "错误:未知参数 $1"
|
|
|
|
|
|
usage
|
|
|
|
|
|
;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
# 校验操作参数
|
|
|
|
|
|
if [[ -z "$ACTION" ]]; then
|
|
|
|
|
|
echo "错误:必须指定 --install 或 --uninstall"
|
|
|
|
|
|
usage
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查root权限
|
|
|
|
|
|
if [[ $EUID -ne 0 ]]; then
|
|
|
|
|
|
echo "错误:脚本必须以root权限运行(使用sudo)"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 获取默认网卡
|
|
|
|
|
|
get_default_interface() {
|
|
|
|
|
|
INTERFACE=$(ip -br link show | grep -v LOOPBACK | awk '{print $1}' | head -n 1)
|
|
|
|
|
|
if [[ -z "$INTERFACE" ]]; then
|
|
|
|
|
|
echo "错误:无法获取默认网卡,请手动检查网络接口"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo "使用默认网卡:$INTERFACE"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 安装keepalived
|
|
|
|
|
|
install_keepalived() {
|
|
|
|
|
|
# 校验安装参数
|
|
|
|
|
|
if [[ -z "$VIP" ]]; then
|
|
|
|
|
|
echo "错误:安装必须指定 --vip(格式:IP/子网掩码)"
|
|
|
|
|
|
usage
|
|
|
|
|
|
fi
|
|
|
|
|
|
if ! [[ "$VIP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
|
|
|
|
|
|
echo "错误:VIP格式无效(正确格式:192.168.1.100/24)"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 获取网卡
|
|
|
|
|
|
get_default_interface
|
|
|
|
|
|
|
|
|
|
|
|
# 安装软件
|
|
|
|
|
|
echo "===== 开始安装keepalived ====="
|
|
|
|
|
|
apt update >/dev/null
|
|
|
|
|
|
apt install -y keepalived >/dev/null || { echo "keepalived安装失败"; exit 1; }
|
|
|
|
|
|
|
|
|
|
|
|
# 备份原有配置(若存在)
|
|
|
|
|
|
if [[ -f "$KEEPALIVED_CONF" ]]; then
|
|
|
|
|
|
mv "$KEEPALIVED_CONF" "${KEEPALIVED_CONF}.bak.$(date +%F_%H%M%S)"
|
|
|
|
|
|
echo "已备份原有配置文件"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 创建健康检查脚本
|
|
|
|
|
|
echo "创建健康检查脚本..."
|
|
|
|
|
|
cat > "$CHECK_SCRIPT" << 'EOF'
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
if ! pgrep -x "haproxy" >/dev/null; then
|
|
|
|
|
|
systemctl stop keepalived
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
else
|
|
|
|
|
|
exit 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
EOF
|
|
|
|
|
|
chmod +x "$CHECK_SCRIPT"
|
|
|
|
|
|
|
|
|
|
|
|
# 生成配置文件
|
|
|
|
|
|
echo "生成keepalived配置..."
|
|
|
|
|
|
cat > "$KEEPALIVED_CONF" << EOF
|
|
|
|
|
|
global_defs {
|
|
|
|
|
|
router_id LVS_K8S_$(hostname)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vrrp_script check_haproxy {
|
|
|
|
|
|
script "$CHECK_SCRIPT"
|
|
|
|
|
|
interval 2
|
|
|
|
|
|
weight -20
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vrrp_instance VI_1 {
|
|
|
|
|
|
state $(if [[ $PRIORITY -ge 150 ]]; then echo "MASTER"; else echo "BACKUP"; fi)
|
|
|
|
|
|
interface $INTERFACE
|
|
|
|
|
|
virtual_router_id 51
|
|
|
|
|
|
priority $PRIORITY
|
|
|
|
|
|
advert_int 1
|
|
|
|
|
|
authentication {
|
|
|
|
|
|
auth_type PASS
|
|
|
|
|
|
auth_pass k8s_ha_auth_2024
|
|
|
|
|
|
}
|
|
|
|
|
|
virtual_ipaddress {
|
|
|
|
|
|
$VIP
|
|
|
|
|
|
}
|
|
|
|
|
|
track_script {
|
|
|
|
|
|
check_haproxy
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
|
|
# 启动服务
|
2025-10-29 20:07:49 +08:00
|
|
|
|
systemctl enable keepalived
|
|
|
|
|
|
systemctl start keepalived
|
2025-10-29 17:36:30 +08:00
|
|
|
|
if systemctl is-active --quiet keepalived; then
|
|
|
|
|
|
echo "===== keepalived安装完成 ====="
|
|
|
|
|
|
echo "VIP:$VIP"
|
|
|
|
|
|
echo "优先级:$PRIORITY"
|
|
|
|
|
|
echo "网卡:$INTERFACE"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "错误:keepalived启动失败,请查看日志 journalctl -u keepalived"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 卸载keepalived
|
|
|
|
|
|
uninstall_keepalived() {
|
|
|
|
|
|
echo "===== 开始卸载keepalived ====="
|
|
|
|
|
|
|
|
|
|
|
|
# 停止服务
|
|
|
|
|
|
if systemctl is-active --quiet keepalived; then
|
|
|
|
|
|
systemctl stop keepalived
|
|
|
|
|
|
echo "已停止keepalived服务"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 卸载软件
|
|
|
|
|
|
if dpkg -l keepalived &>/dev/null; then
|
|
|
|
|
|
apt purge -y keepalived >/dev/null
|
|
|
|
|
|
apt autoremove -y >/dev/null
|
|
|
|
|
|
echo "已卸载keepalived软件包"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "keepalived未安装,跳过卸载"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 清理配置文件(保留备份提示)
|
|
|
|
|
|
if [[ -d /etc/keepalived/ ]]; then
|
|
|
|
|
|
mv /etc/keepalived/ "/etc/keepalived.bak.$(date +%F_%H%M%S)"
|
|
|
|
|
|
echo "配置文件已备份至 /etc/keepalived.bak.xxx"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 清理健康检查脚本
|
|
|
|
|
|
if [[ -f "$CHECK_SCRIPT" ]]; then
|
|
|
|
|
|
rm -f "$CHECK_SCRIPT"
|
|
|
|
|
|
echo "已删除健康检查脚本"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "===== keepalived卸载完成 ====="
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 执行操作
|
|
|
|
|
|
case "$ACTION" in
|
|
|
|
|
|
--install)
|
|
|
|
|
|
install_keepalived
|
|
|
|
|
|
;;
|
|
|
|
|
|
--uninstall)
|
|
|
|
|
|
uninstall_keepalived
|
|
|
|
|
|
;;
|
|
|
|
|
|
*)
|
|
|
|
|
|
usage
|
|
|
|
|
|
;;
|
|
|
|
|
|
esac
|