feat: add deepflow agent playbook and deployment tools

- add initial deepflow-agent-playbook (inventory, playbook, roles)
- add iptables whitelist enforce script
- add deepflow agent batch deploy script
- add initial .gitignore
This commit is contained in:
Haitao Pan 2025-06-16 11:01:52 +08:00
parent 5ed5e7353d
commit 54d6cd3d4a
7 changed files with 428 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
# 忽略所有 .DS_Store 文件
*.DS_Store
# 忽略 playbooks/deepflow 目录下的 tar.gz 文件
playbooks/deepflow/*.zip
playbooks/deepflow/*.tar.gz
playbooks/deepflow/deepflow-agent-playbook/*.zip

View File

@ -0,0 +1,2 @@
ansible-playbook -i inventory/js2_hosts.ini playbook.yml -e "ansible_ssh_user=ubuntu area=js2" -D -C
ansible-playbook -i inventory/js2_hosts.ini playbook.yml -e "ansible_ssh_user=ubuntu area=js2" -D

View File

@ -0,0 +1,8 @@
[js2]
10.200.11.[1:24]
[all:vars]
ansible_port=22
ansible_ssh_user=ubuntu
ansible_host_key_checking=False
ansible_ssh_private_key_file=~/.ssh/id_rsa

View File

@ -0,0 +1,10 @@
- name: DeepFlow Agent Upgrade for 区域节点
hosts: all
become: true
gather_facts: false
vars:
area: js2
upgrade_zip_path: ./DeepFlow-Agent-Upgrade-20250523.zip
roles:
- deepflow_upgrade

View File

@ -0,0 +1,16 @@
- name: Sync upgrade package to remote using rsync
synchronize:
src: "{{ upgrade_zip_path }}"
dest: /tmp/
mode: push
- name: Unzip upgrade package
unarchive:
src: "/tmp/{{ upgrade_zip_path | basename }}"
dest: /tmp/
remote_src: yes
- name: Execute upgrade script
command: bash update_agent.sh --area {{ area }}
args:
chdir: /tmp/DeepFlow-Agent-Upgrade

View File

@ -0,0 +1,265 @@
#!/bin/bash
# FIX config vtap-group-id-request 20250612-15:10
set -e
####################################
# 🌐 配置区
####################################
IP_LIST="./ip.list"
SERVICE_NAME="deepflow-agent"
PKG_DIR="deepflow-agent-for-linux"
MAX_PARALLEL=5
CONTROLLER_IP=""
VTAP_GROUP_ID=""
LIMIT=""
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=15"
FAILED_FILE="failed_hosts.txt"
SUCCESS_FILE="success_hosts.txt"
> "$FAILED_FILE"
> "$SUCCESS_FILE"
####################################
# 参数解析
####################################
if [[ $# -eq 0 ]]; then
echo "用法: $0 {deploy|upgrade|verify} --controller <ip> --group <id> [--limit ip1,ip2]"
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
;;
*)
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]"
exit 1
fi
if [[ "$ACTION" != "verify" && ( -z "$CONTROLLER_IP" || -z "$VTAP_GROUP_ID" ) ]]; then
echo "❗ deploy/upgrade 必须传入 --controller 和 --group 参数"
exit 1
fi
####################################
# 核心函数
####################################
worker() {
local ip="$1"
local user="$2"
local pass="$3"
echo "🔧 [$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
install_agent "$ip" "$user" "$pass" "$pkg_path" && update_config "$ip" "$user" "$pass" && {
echo "$ip $ACTION 完成"
echo "$ip" >> "$SUCCESS_FILE"
} || {
echo "$ip 安装或配置失败"
echo "$ip" >> "$FAILED_FILE"
}
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.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 "🎯 选择安装包: $latest" >&2
echo "$latest"
else
echo "UNSUPPORTED"
fi
}
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"
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<EOF
set -e
if command -v sudo >/dev/null; then SUDO="sudo"; else SUDO=""; fi
if [[ "$remote_pkg" == *.rpm ]]; then
\$SUDO rpm -Uvh --replacepkgs "$remote_pkg"
elif [[ "$remote_pkg" == *.deb ]]; then
\$SUDO dpkg -i "$remote_pkg" || \$SUDO apt-get install -f -y
else
echo "❌ 不支持的安装包格式"
exit 1
fi
if command -v systemctl &>/dev/null; then
\$SUDO systemctl enable $SERVICE_NAME
\$SUDO systemctl restart $SERVICE_NAME
elif command -v service &>/dev/null; then
\$SUDO service $SERVICE_NAME restart
\$SUDO chkconfig $SERVICE_NAME on
elif command -v initctl &>/dev/null; then
\$SUDO initctl restart $SERVICE_NAME || \$SUDO initctl start $SERVICE_NAME
else
echo "❌ 无法识别服务管理方式"
fi
EOF
}
update_config() {
local ip="$1" user="$2" pass="$3"
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" bash <<EOF
set -e
if command -v sudo >/dev/null; then SUDO="sudo"; else SUDO=""; fi
CONFIG_FILE="/etc/deepflow-agent.yaml"
\$SUDO mkdir -p \$(dirname \$CONFIG_FILE)
cat <<CFG | \$SUDO tee "\$CONFIG_FILE" >/dev/null
controller-ips:
- $CONTROLLER_IP
vtap-group-id-request: "$VTAP_GROUP_ID"
CFG
\$SUDO chmod 644 "\$CONFIG_FILE"
\$SUDO chown root:root "\$CONFIG_FILE"
EOF
}
verify_agent() {
local ip="$1" user="$2" pass="$3"
echo "🔍 $ip 状态检查:"
sshpass -p "$pass" ssh $SSH_OPTS "$user@$ip" "
systemctl is-active $SERVICE_NAME 2>/dev/null || \
service $SERVICE_NAME status || \
initctl status $SERVICE_NAME
"
}
####################################
# 并发控制主逻辑
####################################
sem(){
while [[ $(jobs -r | wc -l) -ge $MAX_PARALLEL ]]; do
sleep 0.5
done
}
while read -r ip user pass; do
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 "🎯 全部任务执行完成: 成功 $TOTAL_SUCCESS 台,失败 $TOTAL_FAIL"
if [[ -s "$FAILED_FILE" ]]; then
echo "❗ 失败主机列表已保存: $FAILED_FILE"
fi

View File

@ -0,0 +1,120 @@
#!/bin/bash
# 只使用 iptables 管理白名单控制脚本
# 初始化配置
ALLOW_ALL_IPS=(
127.0.0.1
188.104.180.76 188.104.188.100 188.104.208.200
188.104.198.244 188.104.138.144 188.105.244.69
188.104.229.244 188.104.219.244 188.104.158.196
188.104.174.47 188.104.150.147
188.104.180.88 188.104.180.89 188.104.151.7 188.104.151.8
188.105.215.5 188.105.215.6 188.104.220.8 188.104.220.9
188.104.159.5 188.104.159.6 188.104.190.16 188.104.190.17
188.104.230.5 188.104.230.6 188.104.173.5 188.104.173.6
188.104.199.144 188.104.199.145 188.104.209.49 188.104.209.52
188.104.140.5 188.104.140.6
10.212.222.22 10.212.222.34
188.104.77.15 188.104.77.19
10.76.142.186 10.76.142.187
10.76.149.128
)
ALLOW_CIDRS=(
10.76.144.0/25
188.104.29.0/24
)
ACTION="$1"
if [[ -z "$ACTION" ]]; then
echo "用法: $0 {add|delete|show}"
exit 1
fi
echo ">>> 模式: $ACTION"
echo ">>> 所有非白名单来源将被拒绝"
echo ""
is_ipv6() {
[[ "$1" == *:* ]]
}
run_cmd() {
local cmd="$1"
echo "[RUN] $cmd"
eval "$cmd"
}
# 生成 iptables 规则
generate_iptables_rules() {
# 放行 ICMP 和 ICMPv6 规则(优先级最高)
echo "iptables -I INPUT -p icmp -j ACCEPT"
echo "ip6tables -I INPUT -p ipv6-icmp -j ACCEPT"
# 生成允许的 IP 规则
for ip in "${ALLOW_ALL_IPS[@]}"; do
echo "iptables -I INPUT -s $ip -j ACCEPT"
done
# 生成允许的 CIDR 规则
for cidr in "${ALLOW_CIDRS[@]}"; do
echo "iptables -I INPUT -s $cidr -j ACCEPT"
done
# 默认 DROP 规则
echo "iptables -A INPUT -j DROP"
}
# 删除指定 iptables 规则
delete_iptables_rules() {
# 删除放行 ICMP 和 ICMPv6 规则(优先级最高)
echo "iptables -D INPUT -p icmp -j ACCEPT"
echo "ip6tables -D INPUT -p ipv6-icmp -j ACCEPT"
# 删除允许的 IP 规则
for ip in "${ALLOW_ALL_IPS[@]}"; do
echo "iptables -D INPUT -s $ip -j ACCEPT"
done
# 删除允许的 CIDR 规则
for cidr in "${ALLOW_CIDRS[@]}"; do
echo "iptables -D INPUT -s $cidr -j ACCEPT"
done
# 删除默认 DROP 规则
echo "iptables -D INPUT -j DROP"
}
# 查看当前规则
show_iptables_rules() {
echo "============= iptables -S ============="
iptables -S INPUT | sed 's/^-A /iptables -C /'
echo "============= ip6tables -S ============="
ip6tables -S INPUT | sed 's/^-A /ip6tables -C /'
}
# 执行操作
case "$ACTION" in
add)
generate_iptables_rules > iptables_rules.sh
echo "[INFO] 规则已生成并保存为 iptables_rules.sh 文件"
bash iptables_rules.sh
;;
delete)
delete_iptables_rules > delete_iptables_rules.sh
echo "[INFO] 删除规则已保存为 delete_iptables_rules.sh 文件"
bash delete_iptables_rules.sh
;;
show)
show_iptables_rules
;;
*)
echo "无效的操作: $ACTION"
exit 1
;;
esac
echo ">>> 操作完成。"