From ed0d1ca9049c60b0686a696a9f6d33718e03fb17 Mon Sep 17 00:00:00 2001 From: yuyr Date: Wed, 29 Oct 2025 16:33:38 +0800 Subject: [PATCH] =?UTF-8?q?[#30]=20wsl=E9=83=A8=E7=BD=B2=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=EF=BC=9B=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../all-in-one-full/config/VERSION | 2 +- .../plugins/dcgm-exporter/package.sh | 9 ++++ .../plugins/node-exporter/package.sh | 7 +++ .../scripts/package_artifact.sh | 44 ++++++++++++++- src/sys/tests/.gitignore | 7 +++ src/sys/tests/README.md | 53 ++++++++++++++++--- 6 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 src/sys/tests/.gitignore diff --git a/src/metric/client-plugins/all-in-one-full/config/VERSION b/src/metric/client-plugins/all-in-one-full/config/VERSION index 2aeaa11..bf50e91 100644 --- a/src/metric/client-plugins/all-in-one-full/config/VERSION +++ b/src/metric/client-plugins/all-in-one-full/config/VERSION @@ -1 +1 @@ -1.35.0 +1.37.0 diff --git a/src/metric/client-plugins/all-in-one-full/plugins/dcgm-exporter/package.sh b/src/metric/client-plugins/all-in-one-full/plugins/dcgm-exporter/package.sh index 103913f..53224d2 100755 --- a/src/metric/client-plugins/all-in-one-full/plugins/dcgm-exporter/package.sh +++ b/src/metric/client-plugins/all-in-one-full/plugins/dcgm-exporter/package.sh @@ -48,6 +48,15 @@ if [[ ${#missing_files[@]} -gt 0 ]]; then exit 1 fi +# 防御:阻止将 Git LFS 指针文件打包 +for f in bin/dcgm-exporter bin/datacenter-gpu-manager_3.3.9_amd64.deb; do + if head -n1 "$f" 2>/dev/null | grep -q '^version https://git-lfs.github.com/spec/v1$'; then + echo "[ERROR] $f 是 Git LFS 指针文件,未还原为真实制品" + echo " 请在仓库根目录执行: git lfs fetch --all && git lfs checkout" + exit 1 + fi +done + log_success "所有必要文件检查完成" # 创建临时目录 diff --git a/src/metric/client-plugins/all-in-one-full/plugins/node-exporter/package.sh b/src/metric/client-plugins/all-in-one-full/plugins/node-exporter/package.sh index b38c733..f8c030f 100755 --- a/src/metric/client-plugins/all-in-one-full/plugins/node-exporter/package.sh +++ b/src/metric/client-plugins/all-in-one-full/plugins/node-exporter/package.sh @@ -47,6 +47,13 @@ if [[ ${#missing_files[@]} -gt 0 ]]; then exit 1 fi +# 防御:阻止将 Git LFS 指针文件打包 +if head -n1 bin/node_exporter 2>/dev/null | grep -q '^version https://git-lfs.github.com/spec/v1$'; then + echo "[ERROR] bin/node_exporter 是 Git LFS 指针文件,未还原为真实二进制" + echo " 请在仓库根目录执行: git lfs fetch --all && git lfs checkout" + exit 1 +fi + log_success "所有必要文件检查完成" # 创建临时目录 diff --git a/src/metric/client-plugins/all-in-one-full/scripts/package_artifact.sh b/src/metric/client-plugins/all-in-one-full/scripts/package_artifact.sh index 2c4bb6b..dd8a652 100755 --- a/src/metric/client-plugins/all-in-one-full/scripts/package_artifact.sh +++ b/src/metric/client-plugins/all-in-one-full/scripts/package_artifact.sh @@ -216,6 +216,36 @@ if [[ ${#missing_components[@]} -gt 0 ]]; then exit 1 fi +# 额外校验:阻止将 Git LFS 指针文件打进安装包 +# 仅检查各组件目录下的 bin/ 内文件(常见为二进制或 .deb/.tar.gz 制品) +is_lfs_pointer() { + local f="$1" + # 读取首行判断是否为 LFS pointer(无需依赖 file 命令) + head -n1 "$f" 2>/dev/null | grep -q '^version https://git-lfs.github.com/spec/v1$' +} + +log_info "检查组件二进制是否已从 LFS 拉取..." +while IFS= read -r component; do + component_path=$(grep "^$component:" "$TEMP_DIR/component_paths.txt" | cut -d':' -f2-) + bin_dir="$component_path/bin" + [[ -d "$bin_dir" ]] || continue + while IFS= read -r f; do + # 只检查常见可执行/包后缀;无后缀的也检查 + case "$f" in + *.sh) continue;; + *) :;; + esac + if is_lfs_pointer "$f"; then + log_error "检测到 Git LFS 指针文件: $f" + log_error "请在仓库根目录执行: git lfs fetch --all && git lfs checkout" + log_error "或确保 CI 在打包前已还原 LFS 大文件。" + rm -rf "$TEMP_DIR" + exit 1 + fi + done < <(find "$bin_dir" -maxdepth 1 -type f 2>/dev/null | sort) +done < "$COMPONENTS_FILE" +log_success "LFS 校验通过:未发现指针文件" + # 打包各个组件 log_info "开始打包组件..." @@ -234,7 +264,19 @@ while IFS= read -r component; do # 进入组件目录 cd "$component_path" - + + # 组件内二次防御:若包脚本缺失 LFS 校验,这里再次阻断 + if [[ -d bin ]]; then + for f in bin/*; do + [[ -f "$f" ]] || continue + if head -n1 "$f" 2>/dev/null | grep -q '^version https://git-lfs.github.com/spec/v1$'; then + log_error "组件 $component 含 LFS 指针文件: $f" + log_error "请执行: git lfs fetch --all && git lfs checkout" + cd "$CURRENT_DIR"; rm -rf "$TEMP_DIR"; exit 1 + fi + done + fi + # 检查组件是否有 package.sh if [[ ! -f "package.sh" ]]; then log_error "$component 缺少 package.sh 文件" diff --git a/src/sys/tests/.gitignore b/src/sys/tests/.gitignore new file mode 100644 index 0000000..7986543 --- /dev/null +++ b/src/sys/tests/.gitignore @@ -0,0 +1,7 @@ + +private/ +private-nodea/ +private-nodeb/ +tmp/ + +.env diff --git a/src/sys/tests/README.md b/src/sys/tests/README.md index 964663f..3f4d8be 100644 --- a/src/sys/tests/README.md +++ b/src/sys/tests/README.md @@ -1,13 +1,17 @@ # ARGUS 系统级端到端测试(Sys E2E) -本目录包含将 log 与 agent 两线验证合并后的系统级端到端测试。依赖 bind/master/es/kibana + 两个“日志节点”(每个节点容器内同时运行 Fluent Bit 与 argus-agent)。 +本目录包含将 log、metric 与 agent 三线验证合并后的系统级端到端测试。依赖 bind/master/es/kibana/metric(ftp+prometheus+grafana+alertmanager)/web-proxy/web-frontend + 两个“计算节点”(每个节点容器内同时运行 Fluent Bit 与 argus-agent)。 --- ## 一、如何运行 - 前置条件 - - 已构建镜像:`argus-elasticsearch:latest`、`argus-kibana:latest`、`argus-bind9:latest`、`argus-master:latest` + - 已构建镜像: + - 基座:`argus-elasticsearch:latest`、`argus-kibana:latest`、`argus-bind9:latest`、`argus-master:latest` + - 节点:`argus-sys-node:latest` + - 指标:`argus-metric-ftp:latest`、`argus-metric-prometheus:latest`、`argus-metric-grafana:latest`、`argus-alertmanager:latest` + - 前端与代理:`argus-web-frontend:latest`、`argus-web-proxy:latest` - 可用根目录命令构建:`./build/build_images.sh [--intranet]` - 主机具备 Docker 与 Docker Compose。 @@ -33,11 +37,12 @@ - 一键执行 - `cd src/sys/tests` - `./scripts/00_e2e_test.sh`(CPU-only)或 `./scripts/00_e2e_test.sh --enable-gpu`(启用 GPU 流程) + - 可选:`--no-clean` 跳过清理,便于失败后现场排查 - 分步执行(推荐用于排查) - `./scripts/01_bootstrap.sh` 生成目录/拷贝 `update-dns.sh`/构建 agent 二进制/写 `.env` - `./scripts/02_up.sh` 启动 Compose 栈(工程名 `argus-sys`) - - `./scripts/03_wait_ready.sh` 等待 ES/Kibana/Master/Fluent‑Bit/Bind 就绪(Kibana 必须返回 200 且 overall.level=available) + - `./scripts/03_wait_ready.sh` 等待 ES/Kibana/Master/Fluent‑Bit/Bind/Prometheus/Grafana/Alertmanager/Web‑Proxy 就绪(Kibana 必须 200 且 overall.level=available;Web‑Proxy 8084/8085 要有 CORS 头) - `./scripts/04_verify_dns_routing.sh` 校验 bind 解析与节点内域名解析 - `./scripts/05_agent_register.sh` 获取两个节点的 `node_id` 与初始 IP,检查本地 `node.json` - `./scripts/06_write_health_and_assert.sh` 写健康文件并断言 `nodes.json` 仅包含 2 个在线节点 @@ -60,7 +65,7 @@ ## 二、测试部署架构(docker-compose) - 网络 - - 自定义 bridge:`argus-sys-net`,子网 `172.31.0.0/16` + - 自定义 bridge:`sysnet`(Compose 工程名为 `argus-sys` 时实际为 `argus-sys_sysnet`),子网 `172.31.0.0/16` - 固定地址:bind=`172.31.0.2`,master=`172.31.0.10` - 服务与端口(宿主机映射端口由 `01_bootstrap.sh` 自动分配并写入 `.env`) @@ -68,9 +73,15 @@ - `bind`(`argus-bind9:latest`):监听 53/tcp+udp;负责同步 `*.argus.com` 记录 - `master`(`argus-master:latest`):对外 `${MASTER_PORT}→3000`;API `http://localhost:${MASTER_PORT}` - `es`(`argus-elasticsearch:latest`):`${ES_HTTP_PORT}→9200`;单节点,无安全 - - `kibana`(`argus-kibana:latest`):`${KIBANA_PORT}→5601`;通过 `ELASTICSEARCH_HOSTS=http://es:9200` 访问 ES - - `node-a`(`ubuntu:22.04`):同时运行 Fluent Bit + argus-agent,`hostname=dev-yyrshare-nbnyx10-cp2f-pod-0`,`${NODE_A_PORT}→2020` - - `node-b`(`ubuntu:22.04`):同时运行 Fluent Bit + argus-agent,`hostname=dev-yyrshare-uuuu10-ep2f-pod-0`,`${NODE_B_PORT}→2020` + - `kibana`(`argus-kibana:latest`):`${KIBANA_PORT}→5601` + - `node-a`(`argus-sys-node:latest`):同时运行 Fluent Bit + argus-agent,`hostname=dev-yyrshare-nbnyx10-cp2f-pod-0`,`${NODE_A_PORT}→2020` + - `node-b`(`argus-sys-node:latest`):同时运行 Fluent Bit + argus-agent,`hostname=dev-yyrshare-uuuu10-ep2f-pod-0`,`${NODE_B_PORT}→2020` + - `ftp`(`argus-metric-ftp:latest`):`${FTP_PORT}→21`/`${FTP_DATA_PORT}→20`/`${FTP_PASSIVE_HOST_RANGE}` 被动端口 + - `prometheus`(`argus-metric-prometheus:latest`):`${PROMETHEUS_PORT}→9090` + - `grafana`(`argus-metric-grafana:latest`):`${GRAFANA_PORT}→3000` + - `alertmanager`(`argus-alertmanager:latest`):`${ALERTMANAGER_PORT}→9093` + - `web-frontend`(`argus-web-frontend:latest`):内部访问页面,使用 `web-proxy` 暴露的对外端口渲染超链 + - `web-proxy`(`argus-web-proxy:latest`):多端口转发 8080..8085(首页、Grafana、Prometheus、Kibana、Alertmanager、Master API) - 卷与目录 - 核心服务(bind/master/es/kibana)共享宿主 `./private` 挂载到容器 `/private` @@ -85,7 +96,7 @@ - 节点入口 - `scripts/node_entrypoint.sh`: - - 复制 `/assets/fluent-bit/*` 到容器 `/private`,后台启动 Fluent Bit(监听 2020) + - 离线优先:将 `/assets/fluent-bit/packages` 与 `etc` 拷贝到 `/private`,执行 `/private/start-fluent-bit.sh` 安装/拉起 Fluent Bit(监听 2020) - 以运行用户(映射 UID/GID)前台启动 `argus-agent` - 节点环境变量:`MASTER_ENDPOINT=http://master.argus.com:3000`、`REPORT_INTERVAL_SECONDS=2`、`ES_HOST=es`、`ES_PORT=9200`、`CLUSTER=local`、`RACK=dev` @@ -108,6 +119,10 @@ - Master `/readyz` 成功 - Fluent Bit 指标接口 `:2020/:2021` 可访问 - bind `named-checkconf` 通过 + - Prometheus `/-/ready` 可用 + - Grafana `GET /api/health` 返回 200 且 `database=ok` + - Alertmanager `GET /api/v2/status` 成功 + - Web‑Proxy:8080 首页 200;8083 首页 200/302;8084/8085 对来自 8080 的请求需返回 `Access-Control-Allow-Origin`(CORS) - `04_verify_dns_routing.sh` - 目的:验证从 bind → 节点容器的解析链路 @@ -151,6 +166,28 @@ --- +## 注意事项(2025‑10‑29 更新) + +- 宿主 inotify 限制导致 03 卡住(Fluent Bit in_tail EMFILE) + - 现象:`03_wait_ready.sh` 一直等待 `:2020/:2021 /api/v2/metrics`;节点日志出现 `tail_fs_inotify.c errno=24 Too many open files`,Fluent Bit 启动失败。 + - 根因:宿主 `fs.inotify.max_user_instances` 上限过低(常见默认 128),被其他进程占满;并非容器内 `ulimit -n` 过低。 + - 处理:在宿主执行(临时): + - `sudo sysctl -w fs.inotify.max_user_instances=1024 fs.inotify.max_user_watches=1048576` + - 建议永久:写入 `/etc/sysctl.d/99-argus-inotify.conf` 后 `sudo sysctl --system` + - 提示:节点入口里对 sysctl 的写操作不影响宿主;需在宿主调整。 + +- Metric 安装制品包含 Git LFS 指针导致 node‑exporter 启动失败 + - 现象:第 11 步在线安装后,日志显示 `Node Exporter 服务启动失败`;容器内 `/usr/local/bin/node-exporter` 头部是文本:`version https://git-lfs.github.com/spec/v1`。 + - 根因:发布到 FTP 的安装包在打包前未执行 `git lfs fetch/checkout`,将指针文件打入制品。 + - 处理:在仓库根目录执行 `git lfs fetch --all && git lfs checkout` 后,重跑 `src/metric/tests/scripts/02_publish_artifact.sh` 再重试 `11_metric_node_install.sh`。 + - 防呆:已在 `all-in-one-full/scripts/package_artifact.sh` 与组件 `plugins/*/package.sh` 增加 LFS 指针校验,发现即失败并提示修复。 + +建议: +- 运行前检查宿主 inotify 值(≥1024/≥1048576)与宿主端口占用(8080..8085、9200/5601/9090/9093/2020/2021/32300 等)。 +- 如需排查失败,使用 `--no-clean` 保留现场,配合 `docker logs`、`curl` 与 `tmp/*.json` 进行定位。 + +--- + 如需更严格的断言(例如 Kibana 载入具体插件、ES 文档字段校验),可在 `07_*.sh` 中追加查询与校验逻辑。 ---