gitops/scripts/deploy_deepflow_agent.sh
Haitao Pan ea2bbc6acd refactor(deepflow): split image pull script into arm64/x86
- removed legacy `pull_save_scp_image.sh`
- added separate scripts for arm64 and x86
- updated `images.txt` and `deploy_deepflow_agent.sh`
- adjusted OpenResty config templates (`artifact.conf.j2`, `nginx.conf.j2`)
2025-09-03 08:58:37 +08:00

369 lines
8.5 KiB
Bash
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
set -e
####################################
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 配置区
####################################
IP_LIST="./ip.list"
SERVICE_NAME="deepflow-agent"
PKG_DIR="deepflow-agent-for-linux"
MAX_PARALLEL=5
CONTROLLER_IP=""
VTAP_GROUP_ID=""
LIMIT=""
SUDO_MODE="sudo" # 可选: sudo | sudo-i
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=15"
FAILED_FILE="failed_hosts.txt"
SUCCESS_FILE="success_hosts.txt"
> "$FAILED_FILE"
> "$SUCCESS_FILE"
####################################
# 参数解析(新增 --sudo-mode
####################################
if [[ $# -eq 0 ]]; then
echo "用法: $0 {deploy|upgrade|verify} --controller <ip> --group <id> [--limit ip1,ip2] [--sudo-mode sudo|sudo-i]"
exit 1
fi
ACTION="$1"
shift
while [[ $# -gt 0 ]]; do
case "$1" in
--controller)
CONTROLLER_IP="$2"
shift 2
;;
--group)
VTAP_GROUP_ID="$2"
shift 2
;;
--limit)
LIMIT="$2"
shift 2
;;
--sudo-mode)
case "$2" in
sudo|sudo-i)
SUDO_MODE="$2"
shift 2
;;
*)
echo "❌ --sudo-mode 必须是 'sudo' 或 'sudo-i'"
exit 1
;;
esac
;;
*)
echo "未知参数: $1"
exit 1
;;
esac
done
if [[ "$ACTION" != "deploy" && "$ACTION" != "upgrade" && "$ACTION" != "verify" ]]; then
echo "用法: $0 {deploy|upgrade|verify} --controller <ip> --group <id> [--limit ip1,ip2] [--sudo-mode sudo|sudo-i]"
exit 1
fi
if [[ "$ACTION" != "verify" && ( -z "$CONTROLLER_IP" || -z "$VTAP_GROUP_ID" ) ]]; then
echo "❗ deploy/upgrade 必须传入 --controller 和 --group 参数"
exit 1
fi
####################################
# 核心函数重点修改SUDO 处理 + 重启逻辑)
####################################
worker() {
local ip="$1"
local user="$2"
local pass="$3"
echo "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [$ACTION] 处理主机 $ip ($user)"
if [[ "$ACTION" == "verify" ]]; then
verify_agent "$ip" "$user" "$pass" && {
echo "$ip" >> "$SUCCESS_FILE"
return
} || {
echo "$ip" >> "$FAILED_FILE"
return
}
fi
remote_info=$(fetch_remote_info "$ip" "$user" "$pass") || {
echo "$ip 获取远程信息失败"
echo "$ip" >> "$FAILED_FILE"
return
}
arch=$(echo "$remote_info" | cut -d'|' -f1)
init=$(echo "$remote_info" | cut -d'|' -f2)
if [[ "$init" == "unknown" ]]; then
echo "$ip 不支持的初始化系统: $init"
echo "$ip" >> "$FAILED_FILE"
return
fi
pkg_path=$(choose_agent_package "$arch" "$init")
if [[ "$pkg_path" == "UNSUPPORTED" ]]; then
echo "$ip 无匹配安装包: $arch/$init"
echo "$ip" >> "$FAILED_FILE"
return
fi
# 安装 + 配置
if install_agent "$ip" "$user" "$pass" "$pkg_path" && update_config "$ip" "$user" "$pass"; then
# ✅ 配置完成后,再次重启服务,确保新配置生效
restart_agent_service "$ip" "$user" "$pass" && {
echo "$ip $ACTION 完成"
echo "$ip" >> "$SUCCESS_FILE"
} || {
echo "$ip 服务重启失败"
echo "$ip" >> "$FAILED_FILE"
}
else
echo "$ip 安装或配置失败"
echo "$ip" >> "$FAILED_FILE"
fi
echo "-------------------------------------------"
}
fetch_remote_info() {
local ip="$1" user="$2" pass="$3"
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<'EOF'
arch=$(uname -m)
case "$arch" in
aarch64|arm64) arch="arm" ;;
*) arch="x86" ;;
esac
if command -v systemctl >/dev/null; then init=systemd;
elif command -v initctl >/dev/null; then init=upstart;
else init=unknown; fi
echo "${arch}|${init}"
EOF
}
choose_agent_package() {
local arch="$1" init="$2"
shopt -s nullglob
declare -a patterns
if [[ "$arch" == "arm" ]]; then
patterns=("$PKG_DIR"/deepflow-agent-*.$init-arm.* \
"$PKG_DIR"/deepflow-agent-*.$init-arm64.* \
"$PKG_DIR"/deepflow-agent-*.$init-aarch64.*)
else
patterns=("$PKG_DIR"/deepflow-agent-*.$init-x86.* \
"$PKG_DIR"/deepflow-agent-*.$init.*)
fi
files=()
for pattern in "${patterns[@]}"; do
for file in $pattern; do
files+=("$file")
done
done
if [[ ${#files[@]} -gt 0 ]]; then
latest=$(printf "%s\n" "${files[@]}" | sort -V | tail -1)
echo "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 选择安装包: $latest" >&2
echo "$latest"
else
echo "UNSUPPORTED"
fi
}
# ✅ 修改 install_agent支持 sudo 和 sudo-i
install_agent() {
local ip="$1" user="$2" pass="$3" pkg_path="$4"
local remote_pkg="/tmp/agent.${pkg_path##*.}"
sshpass -p "$pass" scp $SSH_OPTS "$pkg_path" "$user@$ip:$remote_pkg" || {
echo "$ip 上传安装包失败"
return 1
}
# 构建 SUDO 前缀
local SUDO_CMD=""
case "$SUDO_MODE" in
sudo)
SUDO_CMD="sudo"
;;
sudo-i)
SUDO_CMD="sudo -i"
;;
*)
SUDO_CMD="sudo"
;;
esac
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<EOF
set -e
if command -v sudo >/dev/null; then SUDO="sudo"; else SUDO=""; fi
# 使用指定模式
SUDO_MODE_CMD='$SUDO_CMD'
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 使用权限模式: \$SUDO_MODE_CMD"
if [[ "$remote_pkg" == *.rpm ]]; then
\$SUDO_MODE_CMD rpm -Uvh --replacepkgs "$remote_pkg"
elif [[ "$remote_pkg" == *.deb ]]; then
\$SUDO_MODE_CMD dpkg -i "$remote_pkg" || \$SUDO_MODE_CMD apt-get install -f -y
else
echo "❌ 不支持的安装包格式"
exit 1
fi
# 服务管理注意sudo -i 下 systemctl 可能仍可用)
if command -v systemctl &>/dev/null; then
\$SUDO_MODE_CMD systemctl enable $SERVICE_NAME
\$SUDO_MODE_CMD systemctl restart $SERVICE_NAME
elif command -v service &>/dev/null; then
\$SUDO_MODE_CMD service $SERVICE_NAME restart
\$SUDO_MODE_CMD chkconfig $SERVICE_NAME on
elif command -v initctl &>/dev/null; then
\$SUDO_MODE_CMD initctl restart $SERVICE_NAME || \$SUDO_MODE_CMD initctl start $SERVICE_NAME
else
echo "❌ 无法识别服务管理方式"
exit 1
fi
EOF
}
# ✅ 修改 update_config确保配置写入 /etc/
update_config() {
local ip="$1" user="$2" pass="$3"
local SUDO_CMD=""
case "$SUDO_MODE" in
sudo)
SUDO_CMD="sudo"
;;
sudo-i)
SUDO_CMD="sudo -i"
;;
*)
SUDO_CMD="sudo"
;;
esac
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<EOF
set -e
SUDO_MODE_CMD='$SUDO_CMD'
CONFIG_FILE="/etc/deepflow-agent.yaml"
# 使用 sudo -i 创建目录(更可靠)
\$SUDO_MODE_CMD mkdir -p \$(dirname \$CONFIG_FILE)
# 写入配置(使用 tee 避免重定向权限问题)
cat <<'CFG' | \$SUDO_MODE_CMD tee "\$CONFIG_FILE" >/dev/null
controller-ips:
- $CONTROLLER_IP
vtap-group-id: "$VTAP_GROUP_ID"
CFG
\$SUDO_MODE_CMD chmod 644 "\$CONFIG_FILE"
\$SUDO_MODE_CMD chown root:root "\$CONFIG_FILE"
EOF
}
# ✅ 新增函数:服务重启 + 状态检查
restart_agent_service() {
local ip="$1" user="$2" pass="$3"
local SUDO_CMD=""
case "$SUDO_MODE" in
sudo)
SUDO_CMD="sudo"
;;
sudo-i)
SUDO_CMD="sudo -i"
;;
*)
SUDO_CMD="sudo"
;;
esac
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<EOF
set -e
SUDO_MODE_CMD='$SUDO_CMD'
# 重启服务
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 正在重启 deepflow-agent.service 以应用配置..."
\$SUDO_MODE_CMD systemctl restart $SERVICE_NAME
sleep 3
# 检查服务状态
if ! \$SUDO_MODE_CMD systemctl is-active $SERVICE_NAME > /dev/null 2>&1; then
echo "❌ deepflow-agent.service 重启后未运行"
exit 1
fi
echo "✅ deepflow-agent.service 已成功重启"
EOF
}
verify_agent() {
local ip="$1" user="$2" pass="$3"
echo "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> $ip 状态检查:"
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" "
sudo systemctl is-active $SERVICE_NAME 2>/dev/null || \
sudo service $SERVICE_NAME status || \
sudo initctl status $SERVICE_NAME || \
echo '⚠️ 服务状态未知'
"
}
####################################
# 并发控制主逻辑(不变)
####################################
sem(){
while [[ $(jobs -r | wc -l) -ge $MAX_PARALLEL ]]; do
sleep 0.5
done
}
while read -r ip user pass; do
[[ -z "$ip" || "$ip" =~ ^# ]] && continue
if [[ -n "$LIMIT" ]]; then
IFS=',' read -ra LIMIT_IPS <<< "$LIMIT"
skip=true
for lim_ip in "${LIMIT_IPS[@]}"; do
[[ "$ip" == "$lim_ip" ]] && skip=false
done
$skip && continue
fi
sem
worker "$ip" "$user" "$pass" &
done < "$IP_LIST"
wait
TOTAL_SUCCESS=$(wc -l < "$SUCCESS_FILE")
TOTAL_FAIL=$(wc -l < "$FAILED_FILE")
echo "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 全部任务执行完成: 成功 $TOTAL_SUCCESS 台,失败 $TOTAL_FAIL"
if [[ -s "$FAILED_FILE" ]]; then
echo "❗ 失败主机列表已保存: $FAILED_FILE"
fi