[#50] x86机器使用qemu模拟方式安装部署arm版本安装包,当前未精简版,只有简单的node exporter功能,删减日志,GPU指标功能,仍使用Swarm组网
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
argus-sys-net:
|
||||
external: true
|
||||
|
||||
services:
|
||||
metric-cpu-node:
|
||||
image: ${NODE_CPU_IMAGE_TAG:-argus-sys-metric-test-node-arm64:${PKG_VERSION}}
|
||||
platform: linux/arm64
|
||||
container_name: argus-metric-cpu-node
|
||||
hostname: ${CPU_NODE_HOSTNAME}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- DEBIAN_FRONTEND=noninteractive
|
||||
- MASTER_ENDPOINT=${MASTER_ENDPOINT}
|
||||
- ARGUS_BUILD_UID=${ARGUS_BUILD_UID:-2133}
|
||||
- ARGUS_BUILD_GID=${ARGUS_BUILD_GID:-2015}
|
||||
- AGENT_ENV=${AGENT_ENV}
|
||||
- AGENT_USER=${AGENT_USER}
|
||||
- AGENT_INSTANCE=${AGENT_INSTANCE}
|
||||
networks:
|
||||
argus-sys-net:
|
||||
aliases:
|
||||
- ${AGENT_INSTANCE}.node.argus.com
|
||||
volumes:
|
||||
- ../private/argus/agent:/private/argus/agent
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
# ARM Client-CPU 安装指南(client_arm)
|
||||
|
||||
本包用于在 ARM64 CPU 节点上部署 Argus 的最小客户端:
|
||||
|
||||
- `argus-agent`(负责注册/上报状态到 master)
|
||||
- `node-exporter`(暴露该节点的系统指标)
|
||||
|
||||
> 注意:本 ARM 客户端包 **不包含 GPU/DCGM exporter 和 Fluent Bit**,仅用于 CPU 节点 metrics。
|
||||
|
||||
---
|
||||
|
||||
## 1. 前置条件
|
||||
|
||||
- 目标机器为 ARM64(例如:aarch64 服务器 / 节点);
|
||||
- 已安装 Docker 和 docker compose(v2,支持 `docker compose` 命令);
|
||||
- 能访问 master 所在网络,或已经通过 overlay 网络加入到与 server 相同的 `argus-sys-net` 中。
|
||||
|
||||
如采用 overlay 网络(Swarm 模式),需提前创建 `argus-sys-net`:
|
||||
|
||||
```bash
|
||||
docker network create --driver overlay argus-sys-net || true
|
||||
```
|
||||
|
||||
如仅使用本地 bridge 网络,可将 compose 中 `networks: argus-sys-net` 调整为本地自定义 network。
|
||||
|
||||
---
|
||||
|
||||
## 2. 解压和加载镜像
|
||||
|
||||
假设你已经将 `client_arm_YYYYMMDD.tar.gz` 拷贝到 ARM 节点:
|
||||
|
||||
```bash
|
||||
tar -xzf client_arm_YYYYMMDD.tar.gz
|
||||
cd client_arm/YYYYMMDD
|
||||
```
|
||||
|
||||
加载 CPU node 镜像:
|
||||
|
||||
```bash
|
||||
for f in images/*.tar.gz; do
|
||||
gunzip -c "$f" | docker load
|
||||
done
|
||||
```
|
||||
|
||||
可以通过:
|
||||
|
||||
```bash
|
||||
docker images | grep 'argus-sys-metric-test-node-arm64'
|
||||
```
|
||||
|
||||
确认镜像已加载。
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置 .env
|
||||
|
||||
进入 compose 目录:
|
||||
|
||||
```bash
|
||||
cd compose
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
需要填写的关键字段:
|
||||
|
||||
- `MASTER_ENDPOINT`
|
||||
- 例如:`http://master.argus.com:3000` 或 `http://<Server-IP>:32300`
|
||||
- `AGENT_ENV` / `AGENT_USER` / `AGENT_INSTANCE`
|
||||
- 用于识别环境、用户和实例,在 UI 中区分节点:
|
||||
- 示例:`AGENT_ENV=prod`, `AGENT_USER=ops`, `AGENT_INSTANCE=node001`
|
||||
- `CPU_NODE_HOSTNAME`
|
||||
- 节点在配置中的 hostname,一般与宿主 `hostname` 一致,例如 `swarm-metric-node-001`。
|
||||
- `ARGUS_BUILD_UID` / `ARGUS_BUILD_GID`
|
||||
- 用于挂载目录 `/private/argus/agent` 的权限映射。
|
||||
|
||||
例如:
|
||||
|
||||
```env
|
||||
PKG_VERSION=20251124
|
||||
NODE_CPU_IMAGE_TAG=argus-sys-metric-test-node-arm64:20251124
|
||||
|
||||
COMPOSE_PROJECT_NAME=argus-client-arm
|
||||
|
||||
MASTER_ENDPOINT=http://master.argus.com:3000
|
||||
AGENT_ENV=dev2
|
||||
AGENT_USER=yuyr
|
||||
AGENT_INSTANCE=node001sX
|
||||
CPU_NODE_HOSTNAME=swarm-metric-node-001
|
||||
|
||||
ARGUS_BUILD_UID=1000
|
||||
ARGUS_BUILD_GID=1000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 准备挂载目录
|
||||
|
||||
包中已经预创建 `private/argus/agent` 目录:
|
||||
|
||||
- `../private/argus/agent`
|
||||
|
||||
可以根据需要设置所有者和权限:
|
||||
|
||||
```bash
|
||||
cd ..
|
||||
sudo chown -R $UID:$GID private/argus
|
||||
```
|
||||
|
||||
确保与 `.env` 中的 `ARGUS_BUILD_UID/GID` 一致。
|
||||
|
||||
---
|
||||
|
||||
## 5. 启动客户端容器
|
||||
|
||||
在 `compose/` 目录执行:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env up -d
|
||||
```
|
||||
|
||||
查看状态:
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
预期看到:
|
||||
|
||||
- `argus-metric-cpu-node` 处于 `Up` 状态。
|
||||
|
||||
---
|
||||
|
||||
## 6. 在 server 端验证
|
||||
|
||||
在 server 侧(master + Prometheus + Grafana 已经通过 ARM server 包部署):
|
||||
|
||||
1. 在 master 的 UI 或 API 中:
|
||||
- `GET /api/v1/master/nodes` 应能看到新节点,`name=CPU_NODE_HOSTNAME`;
|
||||
2. 在 Prometheus 中:
|
||||
- `up{job="node"}` 中应有当前节点记录,且 `value=1`;
|
||||
- 可以通过 `node_load1{hostname="swarm-metric-node-001"}` 等表达式查看指标;
|
||||
3. 在 Web 门户 / Grafana:
|
||||
- 节点列表页面中能看到该节点;
|
||||
- 通过“按 hostname 的节点面板”查看对应指标。
|
||||
|
||||
---
|
||||
|
||||
## 7. 注意事项
|
||||
|
||||
- ARM 客户端包只负责“CPU 节点 metrics”,不包含 GPU/DCGM 或 Fluent Bit;
|
||||
- 如需要 GPU 支持,请继续使用 `client_gpu` 包,并部署在 x86_64 + NVIDIA GPU 节点上;
|
||||
- ARM 节点的网络连通性(到 master / Prometheus)需要运维侧提前规划;
|
||||
本包不做网络路由/防火墙配置,仅假定可以直接访问 `MASTER_ENDPOINT`。
|
||||
|
||||
105
deployment_new/templates/client_arm/scripts/config.sh
Normal file
105
deployment_new/templates/client_arm/scripts/config.sh
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ARM Client-CPU 配置脚本:
|
||||
# - 读取 server 侧生成的 cluster-info.env(包含 SWARM_MANAGER_ADDR / SWARM_JOIN_TOKEN_WORKER)
|
||||
# - 加入 Swarm(worker)
|
||||
# - 预热 overlay 网络,确保能通过 master.argus.com 访问 server
|
||||
# - 生成/更新 compose/.env(填充 Swarm 相关字段,保留人工填写的 AGENT_*、CPU_NODE_HOSTNAME 等)
|
||||
|
||||
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]\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 ]]; }
|
||||
|
||||
# Compose 检测:优先 docker compose(v2),回退 docker-compose(v1)
|
||||
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; }
|
||||
|
||||
# 磁盘空间检查(MB)
|
||||
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(默认取当前包根,也可用 CLUSTER_INFO 指定路径)
|
||||
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
|
||||
|
||||
# 预热容器(worker 侧加入 overlay 以便本地可见)
|
||||
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; }
|
||||
|
||||
# 通过 warmup 容器测试实际数据通路(alias → master)
|
||||
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 正常)"
|
||||
|
||||
# 生成/更新 .env(保留人工填写项,不覆盖已有键)
|
||||
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 }
|
||||
|
||||
# 写入与 Swarm 相关的字段,便于后续诊断
|
||||
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:-}"
|
||||
|
||||
# 若未显式设置 MASTER_ENDPOINT,则默认走 overlay 别名
|
||||
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/install.sh 启动 ARM Client-CPU"
|
||||
48
deployment_new/templates/client_arm/scripts/install.sh
Normal file
48
deployment_new/templates/client_arm/scripts/install.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ARM Client-CPU 安装脚本:
|
||||
# - 导入 ARM CPU node 镜像
|
||||
# - 启动 compose 中的 metric-cpu-node 服务
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PKG_ROOT="$ROOT_DIR"
|
||||
ENV_FILE="$PKG_ROOT/compose/.env"
|
||||
COMPOSE_FILE="$PKG_ROOT/compose/docker-compose.yml"
|
||||
|
||||
info(){ echo -e "\033[34m[INSTALL-ARM-CLIENT]\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
|
||||
require_compose
|
||||
|
||||
[[ -f "$ENV_FILE" ]] || { err "缺少 compose/.env,请先运行 scripts/config.sh"; exit 1; }
|
||||
info "使用环境文件: $ENV_FILE"
|
||||
|
||||
set -a; source "$ENV_FILE"; set +a
|
||||
|
||||
# 导入 ARM CPU node 镜像
|
||||
IMG_TGZ=$(ls -1 "$PKG_ROOT"/images/argus-sys-metric-test-node-arm64-*.tar.gz 2>/dev/null | head -1 || true)
|
||||
[[ -n "$IMG_TGZ" ]] || { err "找不到 ARM CPU node 镜像 tar.gz(argus-sys-metric-test-node-arm64-*.tar.gz)"; exit 1; }
|
||||
info "导入 ARM CPU node 镜像: $(basename "$IMG_TGZ")"
|
||||
tmp=$(mktemp); gunzip -c "$IMG_TGZ" > "$tmp"; docker load -i "$tmp" >/dev/null; rm -f "$tmp"
|
||||
|
||||
# 确保 agent 挂载目录存在
|
||||
mkdir -p "$PKG_ROOT/private/argus/agent"
|
||||
|
||||
# 启动 compose
|
||||
PROJECT="${COMPOSE_PROJECT_NAME:-argus-client-arm}"
|
||||
info "启动 ARM CPU 节点 (docker compose -p $PROJECT up -d)"
|
||||
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d
|
||||
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" ps
|
||||
|
||||
info "ARM Client-CPU 安装完成。可通过 docker logs -f argus-metric-cpu-node 查看节点容器日志。"
|
||||
|
||||
28
deployment_new/templates/client_arm/scripts/uninstall.sh
Normal file
28
deployment_new/templates/client_arm/scripts/uninstall.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PKG_ROOT="$ROOT_DIR"
|
||||
ENV_FILE="$PKG_ROOT/compose/.env"
|
||||
COMPOSE_FILE="$PKG_ROOT/compose/docker-compose.yml"
|
||||
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
set -a; source "$ENV_FILE"; set +a
|
||||
fi
|
||||
|
||||
PROJECT="${COMPOSE_PROJECT_NAME:-argus-client-arm}"
|
||||
|
||||
err(){ echo -e "\033[31m[ERROR]\033[0m $*" >&2; }
|
||||
|
||||
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_compose
|
||||
|
||||
echo "[UNINSTALL-ARM-CLIENT] stopping compose (project=$PROJECT)"
|
||||
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" down --remove-orphans || true
|
||||
echo "[UNINSTALL-ARM-CLIENT] done"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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" "$@"
|
||||
|
||||
@@ -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" "$@"
|
||||
|
||||
Reference in New Issue
Block a user