[#50] x86机器使用qemu模拟方式安装部署arm版本安装包,当前未精简版,只有简单的node exporter功能,删减日志,GPU指标功能,仍使用Swarm组网

This commit is contained in:
2025-12-01 15:27:12 +08:00
parent 4c45166b44
commit a6e1bf7fe7
26 changed files with 1875 additions and 20 deletions

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
set -euo pipefail
# x86 上安装 ARM Client-CPU 的配置脚本:
# 逻辑与 ARM 版基本一致(读取 cluster-info、加入 Swarm、预热 overlay、生成 .env),只是日志前缀不同。
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PKG_ROOT="$ROOT_DIR"
ENV_EX="$PKG_ROOT/compose/.env.example"
ENV_OUT="$PKG_ROOT/compose/.env"
info(){ echo -e "\033[34m[CONFIG-ARM-CLIENT-X86]\033[0m $*"; }
err(){ echo -e "\033[31m[ERROR]\033[0m $*" >&2; }
require(){ local ok=1; for c in "$@"; do command -v "$c" >/dev/null 2>&1 || { err "缺少依赖: $c"; ok=0; }; done; [[ $ok -eq 1 ]]; }
require_compose(){
if docker compose version >/dev/null 2>&1; then return 0; fi
if command -v docker-compose >/dev/null 2>&1 && docker-compose version >/dev/null 2>&1; then return 0; fi
err "未检测到 Docker Compose,请安装 docker compose v2 或 docker-compose v1"; exit 1
}
require docker curl jq awk sed tar gzip
require_compose
[[ -f "$ENV_EX" ]] || { err "缺少模板文件: $ENV_EX"; exit 1; }
# 磁盘空间检查
check_disk(){ local p="$1"; local need=5120; local free
free=$(df -Pm "$p" | awk 'NR==2{print $4+0}')
if [[ -z "$free" || "$free" -lt "$need" ]]; then err "磁盘空间不足: $p 剩余 ${free:-0}MB (<${need}MB)"; fi
}
check_disk "$PKG_ROOT" || true
check_disk "/var/lib/docker" || true
# 导入 cluster-info.env
CI_IN="${CLUSTER_INFO:-$PKG_ROOT/cluster-info.env}"
info "读取 cluster-info.env: $CI_IN"
[[ -f "$CI_IN" ]] || { err "找不到 cluster-info.env(默认当前包根,或设置环境变量 CLUSTER_INFO 指定绝对路径)"; exit 1; }
set -a; source "$CI_IN"; set +a
[[ -n "${SWARM_MANAGER_ADDR:-}" && -n "${SWARM_JOIN_TOKEN_WORKER:-}" ]] || { err "cluster-info.env 缺少 SWARM 信息(SWARM_MANAGER_ADDR/SWARM_JOIN_TOKEN_WORKER)"; exit 1; }
# 加入 Swarm(幂等)
info "加入 Swarm(幂等):$SWARM_MANAGER_ADDR"
docker swarm join --token "$SWARM_JOIN_TOKEN_WORKER" "$SWARM_MANAGER_ADDR":2377 >/dev/null 2>&1 || true
# 导入 busybox 并做 overlay 预热与连通性
NET_NAME="${ARGUS_OVERLAY_NET:-argus-sys-net}"
if ! docker image inspect busybox:latest >/dev/null 2>&1; then
if [[ -f "$PKG_ROOT/images/busybox.tar" ]]; then
info "加载 busybox.tar 以预热 overlay"
docker load -i "$PKG_ROOT/images/busybox.tar" >/dev/null
else
err "缺少 busybox 镜像(包内 images/busybox.tar 或本地 busybox:latest),无法预热 overlay $NET_NAME"; exit 1
fi
fi
docker rm -f argus-net-warmup >/dev/null 2>&1 || true
info "启动 warmup 容器加入 overlay: $NET_NAME"
docker run -d --rm --name argus-net-warmup --network "$NET_NAME" busybox:latest sleep 600 >/dev/null 2>&1 || true
for i in {1..60}; do docker network inspect "$NET_NAME" >/dev/null 2>&1 && { info "overlay 可见 (t=${i}s)"; break; }; sleep 1; done
docker network inspect "$NET_NAME" >/dev/null 2>&1 || { err "预热后仍未看到 overlay: $NET_NAME;请确认 server 侧 overlay 已创建且可达"; exit 1; }
if ! docker exec argus-net-warmup sh -lc "ping -c 1 -W 2 master.argus.com >/dev/null 2>&1"; then
err "warmup 容器内无法通过别名访问 master.argus.com;请确认 server compose 已启动并加入 overlay $NET_NAME"
exit 1
fi
info "warmup 容器内可达 master.argus.com(Docker DNS + alias 正常)"
if [[ ! -f "$ENV_OUT" ]]; then
cp "$ENV_EX" "$ENV_OUT"
fi
set_kv(){ local k="$1" v="$2"; if grep -q "^${k}=" "$ENV_OUT"; then sed -i -E "s#^${k}=.*#${k}=${v}#" "$ENV_OUT"; else echo "${k}=${v}" >> "$ENV_OUT"; fi }
set_kv SWARM_MANAGER_ADDR "${SWARM_MANAGER_ADDR:-}"
set_kv SWARM_JOIN_TOKEN_WORKER "${SWARM_JOIN_TOKEN_WORKER:-}"
set_kv SWARM_JOIN_TOKEN_MANAGER "${SWARM_JOIN_TOKEN_MANAGER:-}"
if ! grep -q '^MASTER_ENDPOINT=' "$ENV_OUT"; then
echo "MASTER_ENDPOINT=http://master.argus.com:3000" >> "$ENV_OUT"
fi
REQ_VARS=(AGENT_ENV AGENT_USER AGENT_INSTANCE CPU_NODE_HOSTNAME)
missing=()
for v in "${REQ_VARS[@]}"; do
val=$(grep -E "^$v=" "$ENV_OUT" | head -1 | cut -d= -f2-)
if [[ -z "$val" ]]; then missing+=("$v"); fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
err "以下变量必须在 compose/.env 中填写:${missing[*]}(已保留你现有的内容,不会被覆盖)"
exit 1
fi
info "已生成 compose/.env;可执行 scripts_for_x86/install.sh 启动 ARM Client-CPU"

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -euo pipefail
# 在 x86_64 主机上安装 ARM Client-CPU:
# 1) 确认/安装 binfmt + QEMU(通过 tonistiigi/binfmt);
# 2) 调用通用的 scripts/install.sh 启动 ARM CPU node 容器。
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
info(){ echo -e "\033[34m[INSTALL-ARM-CLIENT-X86]\033[0m $*"; }
err(){ echo -e "\033[31m[ERROR-ARM-CLIENT-X86]\033[0m $*" >&2; }
require(){ local ok=1; for c in "$@"; do command -v "$c" >/dev/null 2>&1 || { err "缺少依赖: $c"; ok=0; }; done; [[ $ok -eq 1 ]]; }
ensure_binfmt_arm64() {
info "检查当前主机架构: $(uname -m)"
if [[ "$(uname -m)" != "x86_64" && "$(uname -m)" != "amd64" ]]; then
info "当前并非 x86_64($(uname -m)),通常应直接在 ARM 服务器上使用 scripts/install.sh。继续执行但不强制安装 binfmt。"
return 0
fi
require docker
# 优先使用随安装包一起提供的 ubuntu-22.04-arm-test 镜像做自检
local TEST_IMG="ubuntu:22.04"
local TEST_TAR=""
if [[ -d "$ROOT_DIR/images" ]]; then
TEST_TAR=$(ls "$ROOT_DIR"/images/ubuntu-22.04-arm-test*.tar.gz 2>/dev/null | head -n1 || true)
fi
if [[ -n "$TEST_TAR" && ! $(docker image inspect "$TEST_IMG" >/dev/null 2>&1; echo $?) -eq 0 ]]; then
info "从安装包加载 ARM 测试基础镜像: $(basename "$TEST_TAR")"
tmp=$(mktemp)
gunzip -c "$TEST_TAR" > "$tmp"
docker load -i "$tmp" >/dev/null
rm -f "$tmp"
fi
info "验证是否已能运行 linux/arm64 容器..."
if docker run --rm --platform=linux/arm64 "$TEST_IMG" uname -m 2>/dev/null | grep -q 'aarch64'; then
info "检测到本机已支持 ARM64 容器运行 (uname -m = aarch64)"
return 0
fi
info "未检测到 ARM64 运行能力,尝试通过 tonistiigi/binfmt 安装 binfmt/QEMU ..."
local BINFMT_IMG="tonistiigi/binfmt:latest"
local BINFMT_TAR=""
if [[ -d "$ROOT_DIR/images" ]]; then
BINFMT_TAR=$(ls "$ROOT_DIR"/images/tonistiigi-binfmt*.tar.gz 2>/dev/null | head -n1 || true)
fi
if [[ -n "$BINFMT_TAR" && ! $(docker image inspect "$BINFMT_IMG" >/dev/null 2>&1; echo $?) -eq 0 ]]; then
info "从安装包加载 tonistiigi/binfmt 离线镜像: $(basename "$BINFMT_TAR")"
tmp_b=$(mktemp)
gunzip -c "$BINFMT_TAR" > "$tmp_b"
docker load -i "$tmp_b" >/dev/null
rm -f "$tmp_b"
fi
if ! docker run --privileged --rm "$BINFMT_IMG" --install all; then
err "tonistiigi/binfmt 安装失败,请检查 Docker 权限或确认离线镜像是否完整。"
exit 1
fi
info "再次验证 ARM64 容器可运行状态..."
if ! docker run --rm --platform=linux/arm64 "$TEST_IMG" uname -m 2>/dev/null | grep -q 'aarch64'; then
err "安装 binfmt/QEMU 后仍无法运行 linux/arm64 容器,请手工排查 binfmt_misc 配置。"
exit 1
fi
info "ARM64 容器运行能力检查通过。"
}
ensure_binfmt_arm64
exec "$SCRIPT_DIR/../scripts/install.sh" "$@"

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "$SCRIPT_DIR/../scripts/uninstall.sh" "$@"