Files
go-alived/deployment/check-env.sh
2025-12-08 22:23:45 +08:00

335 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# VIP 环境检测脚本
# 用于检测当前环境是否支持 VRRP 和 VIP 功能
set -e
COLOR_RED='\033[0;31m'
COLOR_GREEN='\033[0;32m'
COLOR_YELLOW='\033[1;33m'
COLOR_BLUE='\033[0;34m'
COLOR_NC='\033[0m'
ERRORS=0
WARNINGS=0
echo -e "${COLOR_BLUE}=== go-alived 环境检测工具 ===${COLOR_NC}"
echo ""
check_pass() {
echo -e "${COLOR_GREEN}${COLOR_NC} $1"
}
check_fail() {
echo -e "${COLOR_RED}${COLOR_NC} $1"
ERRORS=$((ERRORS + 1))
}
check_warn() {
echo -e "${COLOR_YELLOW}${COLOR_NC} $1"
WARNINGS=$((WARNINGS + 1))
}
# 1. 检查是否 root 用户
echo "1. 检查运行权限..."
if [ "$EUID" -eq 0 ]; then
check_pass "以 root 用户运行"
else
check_fail "需要 root 权限,请使用 sudo 运行此脚本"
fi
echo ""
# 2. 检查操作系统
echo "2. 检查操作系统..."
OS=$(uname -s)
if [ "$OS" = "Linux" ]; then
check_pass "操作系统: $OS"
DISTRO=$(cat /etc/os-release | grep ^NAME= | cut -d'"' -f2 || echo "Unknown")
echo " 发行版: $DISTRO"
elif [ "$OS" = "Darwin" ]; then
check_warn "操作系统: macOS - 功能受限,仅支持部分 VRRP 功能"
echo " macOS 不支持某些 Linux 特有的网络功能"
else
check_fail "不支持的操作系统: $OS"
fi
echo ""
# 3. 检查网络接口
echo "3. 检查网络接口..."
read -p "请输入要使用的网卡名称(如 eth0, ens33, en0: " INTERFACE
if ip link show "$INTERFACE" > /dev/null 2>&1; then
check_pass "网卡 $INTERFACE 存在"
# 检查接口状态
STATE=$(ip link show "$INTERFACE" | grep -o "state [A-Z]*" | awk '{print $2}')
if [ "$STATE" = "UP" ]; then
check_pass "网卡状态: UP"
else
check_fail "网卡状态: $STATE (需要是 UP)"
fi
# 检查是否有 IPv4 地址
IP_ADDR=$(ip -4 addr show "$INTERFACE" | grep "inet " | awk '{print $2}' | head -n1)
if [ -n "$IP_ADDR" ]; then
check_pass "网卡已配置 IPv4 地址: $IP_ADDR"
else
check_fail "网卡未配置 IPv4 地址"
fi
else
check_fail "网卡 $INTERFACE 不存在"
echo " 可用网卡列表:"
ip link show | grep "^[0-9]" | awk '{print " - " $2}' | sed 's/:$//'
fi
echo ""
# 4. 检查 VIP 是否可以添加
echo "4. 测试 VIP 添加功能..."
read -p "请输入要测试的 VIP (如 192.168.1.100/24): " TEST_VIP
if [ -n "$TEST_VIP" ] && [ -n "$INTERFACE" ]; then
# 检查 VIP 格式
if [[ $TEST_VIP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
check_pass "VIP 格式正确: $TEST_VIP"
# 尝试添加 VIP
if ip addr add "$TEST_VIP" dev "$INTERFACE" 2>/dev/null; then
check_pass "VIP 添加成功"
# 验证 VIP 是否真的添加了
if ip addr show "$INTERFACE" | grep -q "$TEST_VIP"; then
check_pass "VIP 已添加到网卡"
# 测试 VIP 是否可达(本机 ping
VIP_ADDR=$(echo $TEST_VIP | cut -d'/' -f1)
if ping -c 1 -W 1 "$VIP_ADDR" > /dev/null 2>&1; then
check_pass "VIP 可以 ping 通"
else
check_warn "VIP ping 失败(可能需要配置路由)"
fi
else
check_fail "VIP 添加后无法在网卡上找到"
fi
# 清理:删除测试 VIP
echo " 清理测试 VIP..."
ip addr del "$TEST_VIP" dev "$INTERFACE" 2>/dev/null || true
check_pass "测试 VIP 已删除"
else
check_fail "VIP 添加失败(可能是权限问题或 IP 冲突)"
fi
else
check_fail "VIP 格式错误,正确格式: 192.168.1.100/24"
fi
fi
echo ""
# 5. 检查 VRRP 协议支持
echo "5. 检查 VRRP 协议支持..."
# 检查是否可以创建 raw socket
if [ "$OS" = "Linux" ]; then
if [ -e /proc/sys/net/ipv4/ip_forward ]; then
IP_FORWARD=$(cat /proc/sys/net/ipv4/ip_forward)
if [ "$IP_FORWARD" = "1" ]; then
check_pass "IP 转发已启用"
else
check_warn "IP 转发未启用(某些场景需要)"
echo " 启用命令: echo 1 > /proc/sys/net/ipv4/ip_forward"
fi
fi
fi
# 检查防火墙
echo ""
echo "6. 检查防火墙设置..."
if [ "$OS" = "Linux" ]; then
# 检查 iptables
if command -v iptables > /dev/null 2>&1; then
if iptables -L INPUT -n | grep -q "112"; then
check_pass "防火墙已允许 VRRP 协议 (112)"
else
check_warn "防火墙未配置 VRRP 规则"
echo " 添加规则: iptables -A INPUT -p 112 -j ACCEPT"
fi
fi
# 检查 firewalld
if command -v firewall-cmd > /dev/null 2>&1; then
if systemctl is-active --quiet firewalld; then
if firewall-cmd --list-protocols | grep -q vrrp; then
check_pass "firewalld 已允许 VRRP 协议"
else
check_warn "firewalld 未配置 VRRP 规则"
echo " 添加规则: firewall-cmd --permanent --add-protocol=vrrp"
echo " 重载配置: firewall-cmd --reload"
fi
fi
fi
fi
echo ""
# 7. 检查内核参数
echo "7. 检查内核参数..."
if [ "$OS" = "Linux" ]; then
# 检查 ARP 相关参数
if [ -e /proc/sys/net/ipv4/conf/all/arp_ignore ]; then
ARP_IGNORE=$(cat /proc/sys/net/ipv4/conf/all/arp_ignore)
if [ "$ARP_IGNORE" = "0" ]; then
check_pass "ARP 配置正常"
else
check_warn "ARP ignore 设置为 $ARP_IGNORE,可能影响 VIP"
fi
fi
# 检查 rp_filter
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
RP_FILTER=$(cat /proc/sys/net/ipv4/conf/all/rp_filter)
if [ "$RP_FILTER" = "0" ] || [ "$RP_FILTER" = "2" ]; then
check_pass "反向路径过滤配置正常"
else
check_warn "rp_filter 设置为 $RP_FILTER,建议设置为 0 或 2"
echo " 修改命令: echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter"
fi
fi
fi
echo ""
# 8. 检查是否有其他 VRRP 服务
echo "8. 检查冲突的服务..."
CONFLICT_SERVICES=("keepalived" "vrrpd")
for service in "${CONFLICT_SERVICES[@]}"; do
if systemctl is-active --quiet "$service" 2>/dev/null; then
check_warn "发现运行中的 $service 服务,可能冲突"
echo " 停止命令: systemctl stop $service"
fi
done
if pgrep -x "keepalived" > /dev/null; then
check_warn "发现运行中的 keepalived 进程"
fi
echo ""
# 9. 检查组播支持
echo "9. 检查组播支持..."
if [ -n "$INTERFACE" ]; then
if ip maddr show "$INTERFACE" > /dev/null 2>&1; then
check_pass "网卡支持组播"
# 尝试 ping 组播地址
if timeout 2 ping -c 1 -I "$INTERFACE" 224.0.0.18 > /dev/null 2>&1; then
check_pass "可以发送组播报文"
else
check_warn "组播报文发送可能受限(正常情况)"
fi
else
check_warn "无法查询组播配置"
fi
fi
echo ""
# 10. 虚拟化环境检测
echo "10. 检查虚拟化环境..."
if [ -e /sys/class/dmi/id/product_name ]; then
PRODUCT=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown")
case $PRODUCT in
*VMware*)
check_warn "检测到 VMware 虚拟机"
echo " VMware 需要启用混杂模式才能支持 VRRP"
echo " 设置: 虚拟机 -> 网络适配器 -> 高级 -> 混杂模式: 允许全部"
;;
*VirtualBox*)
check_warn "检测到 VirtualBox 虚拟机"
echo " VirtualBox 需要使用桥接模式且启用混杂模式"
echo " 设置: 网络 -> 桥接网卡 -> 高级 -> 混杂模式: 全部允许"
;;
*KVM*|*QEMU*)
check_pass "检测到 KVM/QEMU 虚拟机(通常支持良好)"
;;
*Amazon*|*EC2*)
check_fail "检测到 AWS EC2 实例 - 不支持 VRRP"
echo " AWS 不支持组播协议,请使用 AWS Elastic IP 替代"
;;
*)
if [ "$PRODUCT" != "Unknown" ]; then
echo " 物理机或未识别的虚拟化: $PRODUCT"
fi
;;
esac
elif command -v systemd-detect-virt > /dev/null 2>&1; then
VIRT=$(systemd-detect-virt)
if [ "$VIRT" != "none" ]; then
check_warn "检测到虚拟化环境: $VIRT"
fi
fi
echo ""
# 11. 云环境检测
echo "11. 检查云环境限制..."
CLOUD_DETECTED=0
# 检查 AWS
if curl -s -m 1 http://169.254.169.254/latest/meta-data/instance-id > /dev/null 2>&1; then
check_fail "检测到 AWS 环境 - 不支持 VRRP"
echo " AWS 不支持 VRRP 协议,请使用:"
echo " - Elastic IP (EIP) 实现 IP 漂移"
echo " - Application Load Balancer (ALB)"
echo " - Network Load Balancer (NLB)"
CLOUD_DETECTED=1
fi
# 检查 阿里云
if curl -s -m 1 http://100.100.100.200/latest/meta-data/instance-id > /dev/null 2>&1; then
check_fail "检测到阿里云 ECS - 不支持 VRRP"
echo " 阿里云 ECS 不支持 VRRP请使用:"
echo " - 负载均衡 SLB"
echo " - 高可用虚拟 IP (HaVip)"
CLOUD_DETECTED=1
fi
# 检查 Azure
if curl -s -m 1 -H "Metadata: true" http://169.254.169.254/metadata/instance?api-version=2021-02-01 > /dev/null 2>&1; then
check_warn "检测到 Azure 环境 - VRRP 支持受限"
echo " Azure 建议使用:"
echo " - Azure Load Balancer"
echo " - Azure Traffic Manager"
CLOUD_DETECTED=1
fi
# 检查 GCP
if curl -s -m 1 -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/id > /dev/null 2>&1; then
check_warn "检测到 Google Cloud 环境 - VRRP 支持受限"
echo " GCP 建议使用:"
echo " - Cloud Load Balancing"
echo " - Forwarding Rules"
CLOUD_DETECTED=1
fi
if [ $CLOUD_DETECTED -eq 0 ]; then
check_pass "未检测到云环境限制"
fi
echo ""
# 总结
echo ""
echo -e "${COLOR_BLUE}=== 检测总结 ===${COLOR_NC}"
echo ""
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e "${COLOR_GREEN}✓ 环境完全支持 go-alived${COLOR_NC}"
echo " 可以正常使用所有功能"
elif [ $ERRORS -eq 0 ]; then
echo -e "${COLOR_YELLOW}⚠ 环境基本支持,但有 $WARNINGS 个警告${COLOR_NC}"
echo " 建议修复警告项以获得更好的稳定性"
else
echo -e "${COLOR_RED}✗ 发现 $ERRORS 个错误, $WARNINGS 个警告${COLOR_NC}"
echo " 请修复错误后再使用 go-alived"
fi
echo ""
echo "详细文档: https://github.com/loveuer/go-alived"
echo ""
exit $ERRORS