1. 背景
最近安装consul加配置很费劲,所以就写了个一键安装的脚本。
1.1. 使用环境
感觉对环境要求不大,此处列出我的使用环境:
- 操作系统:ubuntu20.04
- consul版本:v1.15.3
1.2. 安装准备
需要先下载好consul文件,将正文中的两个脚本内容保存至setupConsul.sh与testConsul.sh文件中,然后与consul放置在同一目录下。如图所示,放置路径随意。
备注:如果觉得单独下载麻烦也可以在脚本中增加下载命令。

1.3. 运行步骤
打开命令行,执行如下命令
# 赋予执行权限并运行
sudo chmod +x setupConsul.sh
./setupConsul.sh
2. 正文
2.1. 安装脚本
setupConsul.sh
#!/bin/bash
# 离线安装 Consul
# ---------- 配置变量 ----------
readonly BIN_DIR="/usr/local/bin"
readonly DATA_DIR="/opt/consul"
readonly CONF_PATH="/etc/consul.d"
readonly CONF_FILE="$CONF_PATH/consul.json"
readonly ADMIN_PASSWORD="1" # 电脑密码需要修改
readonly SERVICE_PATH="/etc/systemd/system"
readonly SERVICE_FILE="$SERVICE_PATH/consul.service"
set -euo pipefail # 启用严格错误处理
# ---------- 函数定义 ----------
# 提权执行函数
run_as_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "$ADMIN_PASSWORD" | sudo -S "$@" 2>/dev/null
else
"$@"
fi
}
# 获取网络IP地址
get_network_ips() {
ip addr | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1
}
# 选择网卡IP地址
select_ip() {
local ips=($(get_network_ips))
local count=${#ips[@]}
if [[ $count -eq 0 ]]; then
echo "❌ 未找到可用网卡" >&2
exit 1
elif [[ $count -eq 1 ]]; then
echo -e "ℹ️ \033[36m检测为单网卡,自动设置IP。\033[0m"
selected_ip="${ips[0]}"
else
echo "🔍 检测到多个网卡,请选择:"
for i in "${!ips[@]}"; do
echo "$((i+1)). ${ips[$i]}"
done
while true; do
read -p "➡️ 请输入选择序号 (1-$count): " choice
if [[ $choice =~ ^[0-9]+$ ]] && ((choice >= 1 && choice <= count)); then
selected_ip="${ips[$((choice-1))]}"
break
else
echo "❌ 无效选择,请重新输入"
fi
done
fi
echo "✅ IP设置为: $selected_ip"
}
# 卸载Consul
uninstall_consul() {
if command -v consul &>/dev/null; then
# 用户确认
echo -e "检测到已安装Consul。按回车继续卸载(Ctrl+C取消)..."
echo -e "\033[33m⚠️ 警告: 若当前节点属于Consul集群!强制卸载可能导致数据不一致。\033[0m"
read -r
# 停止服务
echo "1. 卸载:"
echo "1.1. 停止进程"
if systemctl is-active --quiet consul 2>/dev/null || pgrep -x consul >/dev/null; then
echo "1)停止Consul服务"
run_as_root systemctl stop consul 2>/dev/null || {
echo "2)强制终止残留进程"
run_as_root pkill -9 consul 2>/dev/null
}
sleep 2
fi
# 执行卸载
echo "1.2. 执行卸载"
echo "1)删除二进制文件"
run_as_root rm -f "$BIN_DIR/consul" 2>/dev/null || true
echo "2)删除配置和数据"
run_as_root rm -rf "$CONF_PATH" "$DATA_DIR" 2>/dev/null || true
echo "3)清理系统服务"
run_as_root rm -f "$SERVICE_FILE" 2>/dev/null || true
run_as_root systemctl daemon-reload 2>/dev/null || true
echo "4)删除专用用户"
run_as_root userdel consul 2>/dev/null || true
echo -e "✅ \033[32m卸载完成!\033[0m\n"
else
echo -e "❌ \033[32m系统未安装Consul,跳过卸载\033[0m\n"
fi
}
# 安装二进制文件
install_binary() {
echo "2.1. 安装 Consul 二进制文件"
run_as_root cp "consul" "$BIN_DIR/"
run_as_root chmod +x "$BIN_DIR/consul"
}
# 创建用户和目录
setup_dirs_and_user() {
echo "2.2. 创建系统用户和目录"
id -u consul &>/dev/null || run_as_root useradd --system --home "$CONF_PATH" --shell /bin/false consul
run_as_root mkdir -p "$DATA_DIR" "$CONF_PATH" "$SERVICE_PATH"
run_as_root chmod 777 -R "$DATA_DIR" "$CONF_PATH" "$SERVICE_PATH"
echo -e "✅ \033[32m安装完成!\033[0m\n"
}
# 生成配置文件
generate_config() {
echo "2.3. 生成 JSON 配置文件"
cat > "$CONF_FILE" << EOF
{
"data_dir": "$DATA_DIR",
"node_name": "node1",
"server": true,
"bind_addr": "$selected_ip",
"client_addr": "0.0.0.0",
"bootstrap_expect": 3,
"log_level": "INFO",
"retry_join":["$selected_ip","192.168.187.133","192.168.187.134"],
"ui_config": {
"enabled": true
}
}
EOF
# 验证配置文件
if ! consul validate /etc/consul.d/; then
echo "❌ 配置验证失败"
fi
}
# 配置系统服务
setup_systemd_service() {
echo "配置 Systemd 服务"
cat > "$SERVICE_FILE" << EOF
[Unit]
Description=Consul Service Discovery Agent
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
}
# 启动服务
start_consul_service() {
echo "启动 Consul 服务"
run_as_root systemctl daemon-reload
run_as_root systemctl enable consul
run_as_root systemctl start consul
}
# 验证安装
verify_installation() {
echo -e "4.验证:可以点击ctrl+左键,访问Web UI:\033[34mhttp://$selected_ip:8500/ui\033[0m"
local consul_version_output=$(consul --version 2>&1)
local exit_code=$?
if [[ $exit_code -eq 0 ]]; then
if [[ $consul_version_output =~ [Cc]onsul[[:space:]]+v?[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo -e "✅ \033[32m安装成功!\033[0m\n"
echo -e "ℹ️ \033[36m版本信息:\033[0m\n$consul_version_output\n"
else
echo "❌ 输出异常:未识别到版本号" >&2
echo "输出内容:$consul_version_output" >&2
fi
else
case $exit_code in
127) echo "❌ Consul 未安装:命令不存在" >&2 ;;
*) echo "❌ Consul 执行失败(错误码 $exit_code)" >&2
echo "输出内容:$consul_version_output" >&2 ;;
esac
fi
}
# 验证运行状态
verify_running_status() {
echo -en "5. 运行:等待服务初始化(约3秒)"
gnome-terminal --tab -t "单节点启动consul" -- bash -c \
"echo '单节点启动consul...';
consul agent -dev -config-dir=/etc/consul.d -bootstrap-expect=1
exec bash;"
# 健康检查等待
for i in {1..3}; do
echo -n "."
sleep 1
done
echo
./testConsul.sh
}
# ---------- 主执行流程 ----------
main() {
# 卸载检测
uninstall_consul
# 安装步骤
echo "2. 安装:"
install_binary
setup_dirs_and_user
echo "3. 设置:"
select_ip
generate_config
# 以下服务配置可根据需要取消注释
# setup_systemd_service
# start_consul_service
echo -e "✅ \033[32m设置完成!\033[0m\n"
# 验证安装
verify_installation
# 验证运行状态
verify_running_status
}
# 执行主函数
main
2.2.测试脚本
#!/bin/bash
# 运行 consul members 并捕获输出及状态码
members_output=$(consul members 2>&1)
exit_code=$?
# 判断基础状态./
if [[ $exit_code -ne 0 ]]; then
echo -e "\033[31m❌ Consul 未运行或命令执行失败 (错误码: $exit_code)\033[0m"
echo "错误详情:$members_output"
fi
# 解析节点状态
alive_nodes=0
failed_nodes=0
server_nodes=0
leader_found=0
while read -r line; do
# 跳过标题行
[[ $line == Node* ]] && continue
# 提取关键字段
status=$(echo "$line" | awk '{print $3}')
type=$(echo "$line" | awk '{print $4}')
# 统计节点状态
case "$status" in
alive)
((alive_nodes++))
[[ $type == server ]] && ((server_nodes++))
;;
failed)
((failed_nodes++))
;;
esac
# 检查 Leader 状态
if [[ $line == *leader* ]]; then
leader_found=1
fi
done <<< "$members_output"
# 输出集群状态报告
echo -e "\033[36mℹ️ 集群状态:\033[0m"
echo "存活节点: $alive_nodes 故障节点: $failed_nodes"
echo "Server 节点: $server_nodes Leader 存在: $([ $leader_found -eq 1 ] && echo "是" || echo "否")"
# 健康状态判断
if (( failed_nodes > 0 )); then
echo -e "\n\033[31m■ 严重: 存在故障节点!需立即处理。\033[0m"
consul members | grep failed
elif (( server_nodes == 0 )); then
echo -e "\n\033[33m⚠️ 警告: 无 Server 节点,集群功能受限。\033[0m"
elif [[ $leader_found -eq 0 ]]; then
echo -e "\n\033[33m⚠️ 警告: 未检测到 Leader,可能影响写操作。\033[0m"
consul operator raft list-peers
else
echo -e "\n\033[32m● 健康: 集群运行正常。\033[0m"
fi
结语
如果有帮到您,请点个免费的赞,感谢!如果有别的需求,可以留言或发送邮件到200919854@qq.com。
8823

被折叠的 条评论
为什么被折叠?



