wip v1.0.0
This commit is contained in:
269
deployment/COMPATIBILITY.md
Normal file
269
deployment/COMPATIBILITY.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# VRRP 环境兼容性说明
|
||||
|
||||
## 支持的环境
|
||||
|
||||
### ✅ 完全支持
|
||||
- **物理服务器**: 完全支持所有功能
|
||||
- **本地虚拟机(网络配置正确)**:
|
||||
- KVM/QEMU: 完全支持
|
||||
- Proxmox VE: 完全支持
|
||||
- VMware ESXi: 需要启用混杂模式
|
||||
- VirtualBox: 需要桥接网络 + 混杂模式
|
||||
- Hyper-V: 需要外部网络交换机
|
||||
|
||||
### ⚠️ 部分支持
|
||||
- **某些私有云环境**: 取决于网络配置
|
||||
- **Docker 容器**: 需要 `--privileged` 和 `--net=host` 模式
|
||||
- **Kubernetes**: 需要 hostNetwork 模式
|
||||
|
||||
### ❌ 不支持
|
||||
- **AWS EC2**: 不支持组播,无法运行 VRRP
|
||||
- **阿里云 ECS**: 不支持组播,无法运行 VRRP
|
||||
- **Azure VM**: 默认不支持,需要特殊配置
|
||||
- **Google Cloud**: 默认不支持组播
|
||||
- **大多数公有云**: 网络虚拟化层面禁用了组播
|
||||
|
||||
## 为什么云环境不支持 VRRP?
|
||||
|
||||
1. **组播协议限制**: VRRP 使用 IP 组播地址 224.0.0.18,云环境网络虚拟化层通常过滤组播流量
|
||||
2. **安全考虑**: 云厂商不希望用户自行管理 IP 漂移,避免 IP 冲突
|
||||
3. **网络架构**: SDN (软件定义网络) 架构不支持传统的 MAC 地址漂移
|
||||
|
||||
## 云环境替代方案
|
||||
|
||||
### AWS
|
||||
```yaml
|
||||
方案1: Elastic IP (EIP)
|
||||
- 使用 AWS API 动态绑定/解绑 EIP
|
||||
- 结合健康检查脚本实现故障切换
|
||||
|
||||
方案2: Application Load Balancer (ALB)
|
||||
- 7层负载均衡
|
||||
- 自动健康检查和故障切换
|
||||
|
||||
方案3: Network Load Balancer (NLB)
|
||||
- 4层负载均衡
|
||||
- 支持静态 IP
|
||||
```
|
||||
|
||||
### 阿里云
|
||||
```yaml
|
||||
方案1: 高可用虚拟IP (HaVip)
|
||||
- 阿里云提供的 VRRP 替代方案
|
||||
- 支持主备切换
|
||||
|
||||
方案2: 负载均衡 SLB
|
||||
- 4层/7层负载均衡
|
||||
- 自动健康检查
|
||||
```
|
||||
|
||||
### Azure
|
||||
```yaml
|
||||
方案1: Azure Load Balancer
|
||||
- 标准负载均衡器
|
||||
- 支持高可用性
|
||||
|
||||
方案2: Azure Traffic Manager
|
||||
- DNS 级别的流量管理
|
||||
- 支持多区域故障切换
|
||||
```
|
||||
|
||||
## 虚拟化环境配置指南
|
||||
|
||||
### VMware ESXi
|
||||
1. 选择虚拟机
|
||||
2. 编辑设置 → 网络适配器
|
||||
3. 展开 "高级选项"
|
||||
4. 混杂模式: **允许**
|
||||
5. MAC 地址更改: **允许**
|
||||
6. 伪传输: **允许**
|
||||
|
||||
### VirtualBox
|
||||
1. 虚拟机设置 → 网络
|
||||
2. 连接方式: **桥接网卡**
|
||||
3. 高级 → 混杂模式: **全部允许**
|
||||
4. 高级 → 接入网线: **勾选**
|
||||
|
||||
### KVM/libvirt
|
||||
```xml
|
||||
<interface type='bridge'>
|
||||
<source bridge='br0'/>
|
||||
<model type='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
||||
</interface>
|
||||
```
|
||||
|
||||
### Proxmox VE
|
||||
默认配置即可支持,使用 vmbr0 桥接网络。
|
||||
|
||||
## 检测脚本使用
|
||||
|
||||
运行环境检测脚本:
|
||||
|
||||
```bash
|
||||
# 下载并运行检测脚本
|
||||
sudo ./deployment/check-env.sh
|
||||
```
|
||||
|
||||
脚本会自动检测:
|
||||
1. ✓ 运行权限(root)
|
||||
2. ✓ 操作系统兼容性
|
||||
3. ✓ 网络接口状态
|
||||
4. ✓ VIP 添加能力
|
||||
5. ✓ VRRP 协议支持
|
||||
6. ✓ 防火墙配置
|
||||
7. ✓ 内核参数
|
||||
8. ✓ 服务冲突检测
|
||||
9. ✓ 组播支持
|
||||
10. ✓ 虚拟化环境
|
||||
11. ✓ 云环境限制
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
### 1. VIP 无法添加
|
||||
|
||||
**症状**: `ip addr add` 命令失败
|
||||
|
||||
**可能原因**:
|
||||
- 权限不足(需要 root)
|
||||
- IP 地址冲突
|
||||
- 网络接口不存在或未启动
|
||||
- 子网掩码错误
|
||||
|
||||
**解决方法**:
|
||||
```bash
|
||||
# 检查网卡状态
|
||||
ip link show eth0
|
||||
|
||||
# 检查 IP 冲突
|
||||
arping -I eth0 192.168.1.100
|
||||
|
||||
# 手动测试添加
|
||||
sudo ip addr add 192.168.1.100/24 dev eth0
|
||||
```
|
||||
|
||||
### 2. VIP 添加成功但无法 Ping 通
|
||||
|
||||
**可能原因**:
|
||||
- 防火墙阻止 ICMP
|
||||
- 路由配置错误
|
||||
- ARP 表未更新
|
||||
- 网络隔离(VLAN)
|
||||
|
||||
**解决方法**:
|
||||
```bash
|
||||
# 发送免费 ARP
|
||||
arping -c 3 -A -I eth0 192.168.1.100
|
||||
|
||||
# 检查路由
|
||||
ip route show
|
||||
|
||||
# 检查防火墙
|
||||
iptables -L -n | grep ICMP
|
||||
```
|
||||
|
||||
### 3. VRRP 报文无法发送/接收
|
||||
|
||||
**症状**: 双节点无法选举 Master
|
||||
|
||||
**可能原因**:
|
||||
- 组播被过滤
|
||||
- 防火墙阻止协议 112
|
||||
- 网络交换机禁用组播
|
||||
- 虚拟机混杂模式未启用
|
||||
|
||||
**解决方法**:
|
||||
```bash
|
||||
# 抓包验证 VRRP 报文
|
||||
sudo tcpdump -i eth0 proto 112 -v
|
||||
|
||||
# 检查组播路由
|
||||
ip maddr show eth0
|
||||
|
||||
# 添加防火墙规则
|
||||
sudo iptables -A INPUT -p 112 -j ACCEPT
|
||||
sudo iptables -A OUTPUT -p 112 -j ACCEPT
|
||||
```
|
||||
|
||||
### 4. 云环境 VRRP 不工作
|
||||
|
||||
**确认方法**:
|
||||
```bash
|
||||
# 运行检测脚本
|
||||
sudo ./deployment/check-env.sh
|
||||
|
||||
# 手动检查云环境
|
||||
curl -s -m 1 http://169.254.169.254/latest/meta-data/instance-id
|
||||
```
|
||||
|
||||
**解决方案**: 使用云厂商提供的高可用方案(见上方"云环境替代方案")
|
||||
|
||||
## 网络环境要求
|
||||
|
||||
### 必需条件
|
||||
- [x] 二层网络连通(同一 VLAN/子网)
|
||||
- [x] 支持组播(224.0.0.18)
|
||||
- [x] 允许 ARP 广播
|
||||
- [x] 网卡支持混杂模式(虚拟机环境)
|
||||
|
||||
### 推荐配置
|
||||
- [x] 千兆以上网络
|
||||
- [x] 低延迟网络(< 10ms)
|
||||
- [x] 禁用 STP 或配置 PortFast(交换机)
|
||||
- [x] 专用 VLAN(生产环境)
|
||||
|
||||
## 测试步骤
|
||||
|
||||
### 1. 基础网络测试
|
||||
```bash
|
||||
# 测试网卡连通性
|
||||
ping -c 3 <对端IP>
|
||||
|
||||
# 测试组播连通性(需要两台机器)
|
||||
# 机器 A
|
||||
iperf3 -s -B 224.0.0.18
|
||||
|
||||
# 机器 B
|
||||
iperf3 -c 224.0.0.18 -u -b 1M
|
||||
```
|
||||
|
||||
### 2. VIP 手动测试
|
||||
```bash
|
||||
# 添加 VIP
|
||||
sudo ip addr add 192.168.1.100/24 dev eth0
|
||||
|
||||
# 发送免费 ARP
|
||||
sudo arping -c 3 -A -I eth0 192.168.1.100
|
||||
|
||||
# 从其他机器 ping VIP
|
||||
ping 192.168.1.100
|
||||
|
||||
# 删除 VIP
|
||||
sudo ip addr del 192.168.1.100/24 dev eth0
|
||||
```
|
||||
|
||||
### 3. VRRP 功能测试
|
||||
```bash
|
||||
# 使用最小配置启动
|
||||
sudo ./go-alived --config config.mini.yaml --debug
|
||||
|
||||
# 另一个终端监控网卡
|
||||
watch -n 1 "ip addr show eth0 | grep inet"
|
||||
|
||||
# 抓包验证
|
||||
sudo tcpdump -i eth0 proto 112 -v
|
||||
```
|
||||
|
||||
## 生产环境部署建议
|
||||
|
||||
1. **使用专用网络**: 将 VRRP 流量与业务流量隔离
|
||||
2. **配置监控**: 监控 VIP 状态、VRRP 状态变化
|
||||
3. **测试故障切换**: 定期测试主备切换是否正常
|
||||
4. **文档记录**: 记录网络拓扑、IP 分配、故障处理流程
|
||||
5. **备份配置**: 定期备份 go-alived 配置文件
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [VRRP RFC 3768](https://tools.ietf.org/html/rfc3768)
|
||||
- [Linux IP 命令手册](https://man7.org/linux/man-pages/man8/ip.8.html)
|
||||
- [iptables VRRP 配置](https://www.netfilter.org/)
|
||||
166
deployment/README.md
Normal file
166
deployment/README.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# go-alived Deployment
|
||||
|
||||
本目录包含 go-alived 的部署文件和安装脚本。
|
||||
|
||||
## Systemd Service
|
||||
|
||||
### 安装步骤
|
||||
|
||||
1. **编译二进制文件**
|
||||
```bash
|
||||
go build -o go-alived .
|
||||
```
|
||||
|
||||
2. **安装二进制文件**
|
||||
```bash
|
||||
sudo cp go-alived /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/go-alived
|
||||
```
|
||||
|
||||
3. **创建配置目录**
|
||||
```bash
|
||||
sudo mkdir -p /etc/go-alived
|
||||
sudo mkdir -p /etc/go-alived/scripts
|
||||
```
|
||||
|
||||
4. **复制配置文件**
|
||||
```bash
|
||||
sudo cp config.example.yaml /etc/go-alived/config.yaml
|
||||
sudo vim /etc/go-alived/config.yaml # 根据实际环境修改配置
|
||||
```
|
||||
|
||||
5. **安装 systemd 服务**
|
||||
```bash
|
||||
sudo cp deployment/go-alived.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
6. **启动服务**
|
||||
```bash
|
||||
# 启动服务
|
||||
sudo systemctl start go-alived
|
||||
|
||||
# 查看状态
|
||||
sudo systemctl status go-alived
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u go-alived -f
|
||||
|
||||
# 设置开机自启
|
||||
sudo systemctl enable go-alived
|
||||
```
|
||||
|
||||
### 服务管理命令
|
||||
|
||||
```bash
|
||||
# 启动服务
|
||||
sudo systemctl start go-alived
|
||||
|
||||
# 停止服务
|
||||
sudo systemctl stop go-alived
|
||||
|
||||
# 重启服务
|
||||
sudo systemctl restart go-alived
|
||||
|
||||
# 重载配置(发送 SIGHUP 信号)
|
||||
sudo systemctl reload go-alived
|
||||
|
||||
# 查看服务状态
|
||||
sudo systemctl status go-alived
|
||||
|
||||
# 查看实时日志
|
||||
sudo journalctl -u go-alived -f
|
||||
|
||||
# 查看最近的日志
|
||||
sudo journalctl -u go-alived -n 100
|
||||
|
||||
# 启用开机自启
|
||||
sudo systemctl enable go-alived
|
||||
|
||||
# 禁用开机自启
|
||||
sudo systemctl disable go-alived
|
||||
```
|
||||
|
||||
## Service 文件说明
|
||||
|
||||
### 主要配置项
|
||||
|
||||
- **ExecStart**: 服务启动命令,指向 `/usr/local/bin/go-alived`
|
||||
- **ExecReload**: 重载配置命令(发送 SIGHUP 信号)
|
||||
- **User/Group**: 以 root 用户运行(需要 raw socket 和网络接口管理权限)
|
||||
- **Restart**: 失败时自动重启,间隔 5 秒
|
||||
|
||||
### 安全设置
|
||||
|
||||
- **Capabilities**:
|
||||
- `CAP_NET_ADMIN`: 管理网络接口(添加/删除 IP)
|
||||
- `CAP_NET_RAW`: 创建原始 socket(VRRP 协议)
|
||||
- `CAP_NET_BIND_SERVICE`: 绑定特权端口(可选)
|
||||
|
||||
- **Protection**:
|
||||
- `ProtectSystem=strict`: 保护系统目录只读
|
||||
- `ProtectHome=true`: 保护用户主目录
|
||||
- `PrivateTmp=true`: 使用私有临时目录
|
||||
- `ReadWritePaths=/etc/go-alived`: 仅允许写入配置目录
|
||||
|
||||
### 资源限制
|
||||
|
||||
- `LimitNOFILE=65535`: 最大打开文件数
|
||||
- `LimitNPROC=512`: 最大进程数
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
默认配置文件位置:`/etc/go-alived/config.yaml`
|
||||
|
||||
推荐的目录结构:
|
||||
```
|
||||
/etc/go-alived/
|
||||
├── config.yaml # 主配置文件
|
||||
└── scripts/ # 脚本目录
|
||||
├── notify_master.sh # Master 状态通知脚本
|
||||
├── notify_backup.sh # Backup 状态通知脚本
|
||||
├── notify_fault.sh # Fault 状态通知脚本
|
||||
└── check_service.sh # 健康检查脚本
|
||||
```
|
||||
|
||||
## 卸载
|
||||
|
||||
```bash
|
||||
# 停止并禁用服务
|
||||
sudo systemctl stop go-alived
|
||||
sudo systemctl disable go-alived
|
||||
|
||||
# 删除服务文件
|
||||
sudo rm /etc/systemd/system/go-alived.service
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
# 删除二进制文件
|
||||
sudo rm /usr/local/bin/go-alived
|
||||
|
||||
# 删除配置文件(可选)
|
||||
sudo rm -rf /etc/go-alived
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 查看服务状态
|
||||
```bash
|
||||
sudo systemctl status go-alived
|
||||
```
|
||||
|
||||
### 查看详细日志
|
||||
```bash
|
||||
sudo journalctl -u go-alived -n 100 --no-pager
|
||||
```
|
||||
|
||||
### 测试配置文件
|
||||
```bash
|
||||
/usr/local/bin/go-alived --config /etc/go-alived/config.yaml --debug
|
||||
```
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **权限错误**: 确保服务以 root 运行或具有 CAP_NET_ADMIN/CAP_NET_RAW 权限
|
||||
2. **网卡不存在**: 检查配置文件中的 interface 是否正确
|
||||
3. **端口冲突**: 确保没有其他 keepalived 或 VRRP 服务在运行
|
||||
4. **VIP 添加失败**: 检查网络配置和 IP 地址是否冲突
|
||||
334
deployment/check-env.sh
Executable file
334
deployment/check-env.sh
Executable file
@@ -0,0 +1,334 @@
|
||||
#!/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
|
||||
38
deployment/go-alived.service
Normal file
38
deployment/go-alived.service
Normal file
@@ -0,0 +1,38 @@
|
||||
[Unit]
|
||||
Description=Go-Alived - VRRP High Availability Service
|
||||
Documentation=https://github.com/loveuer/go-alived
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
ExecStart=/usr/local/bin/go-alived --config /etc/go-alived/config.yaml
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=go-alived
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=false
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/etc/go-alived
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=512
|
||||
|
||||
# Capabilities required for VRRP operations
|
||||
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
53
deployment/install.sh
Executable file
53
deployment/install.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Installing go-alived ==="
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BINARY_PATH="/usr/local/bin/go-alived"
|
||||
CONFIG_DIR="/etc/go-alived"
|
||||
SERVICE_FILE="/etc/systemd/system/go-alived.service"
|
||||
|
||||
echo "1. Installing binary to ${BINARY_PATH}..."
|
||||
if [ ! -f "go-alived" ]; then
|
||||
echo "Error: go-alived binary not found. Please run 'go build' first."
|
||||
exit 1
|
||||
fi
|
||||
cp go-alived ${BINARY_PATH}
|
||||
chmod +x ${BINARY_PATH}
|
||||
echo " ✓ Binary installed"
|
||||
|
||||
echo "2. Creating configuration directory ${CONFIG_DIR}..."
|
||||
mkdir -p ${CONFIG_DIR}
|
||||
mkdir -p ${CONFIG_DIR}/scripts
|
||||
echo " ✓ Directories created"
|
||||
|
||||
if [ ! -f "${CONFIG_DIR}/config.yaml" ]; then
|
||||
echo "3. Installing example configuration..."
|
||||
cp config.example.yaml ${CONFIG_DIR}/config.yaml
|
||||
echo " ✓ Configuration installed to ${CONFIG_DIR}/config.yaml"
|
||||
echo " ⚠ Please edit ${CONFIG_DIR}/config.yaml before starting the service"
|
||||
else
|
||||
echo "3. Configuration already exists at ${CONFIG_DIR}/config.yaml"
|
||||
echo " ⚠ Skipping configuration installation"
|
||||
fi
|
||||
|
||||
echo "4. Installing systemd service..."
|
||||
cp deployment/go-alived.service ${SERVICE_FILE}
|
||||
systemctl daemon-reload
|
||||
echo " ✓ Service installed"
|
||||
|
||||
echo ""
|
||||
echo "=== Installation complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Edit configuration: vim ${CONFIG_DIR}/config.yaml"
|
||||
echo " 2. Start service: systemctl start go-alived"
|
||||
echo " 3. Check status: systemctl status go-alived"
|
||||
echo " 4. View logs: journalctl -u go-alived -f"
|
||||
echo " 5. Enable autostart: systemctl enable go-alived"
|
||||
echo ""
|
||||
53
deployment/uninstall.sh
Executable file
53
deployment/uninstall.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Uninstalling go-alived ==="
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BINARY_PATH="/usr/local/bin/go-alived"
|
||||
CONFIG_DIR="/etc/go-alived"
|
||||
SERVICE_FILE="/etc/systemd/system/go-alived.service"
|
||||
|
||||
if systemctl is-active --quiet go-alived; then
|
||||
echo "1. Stopping service..."
|
||||
systemctl stop go-alived
|
||||
echo " ✓ Service stopped"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet go-alived 2>/dev/null; then
|
||||
echo "2. Disabling service..."
|
||||
systemctl disable go-alived
|
||||
echo " ✓ Service disabled"
|
||||
fi
|
||||
|
||||
if [ -f "${SERVICE_FILE}" ]; then
|
||||
echo "3. Removing service file..."
|
||||
rm ${SERVICE_FILE}
|
||||
systemctl daemon-reload
|
||||
echo " ✓ Service file removed"
|
||||
fi
|
||||
|
||||
if [ -f "${BINARY_PATH}" ]; then
|
||||
echo "4. Removing binary..."
|
||||
rm ${BINARY_PATH}
|
||||
echo " ✓ Binary removed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "Do you want to remove configuration directory ${CONFIG_DIR}? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
if [ -d "${CONFIG_DIR}" ]; then
|
||||
rm -rf ${CONFIG_DIR}
|
||||
echo " ✓ Configuration removed"
|
||||
fi
|
||||
else
|
||||
echo " ⚠ Configuration kept at ${CONFIG_DIR}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Uninstallation complete ==="
|
||||
Reference in New Issue
Block a user