sskj/deploy/verify_profile.sh
yy-fighting 5c749cda03 feat(pro6000/GLM-5.3): 方案 D/E/F 部署资产入库(TP2PP4 生产配方 / TP8+DFlash2 / PD 分离四角色链)
- scripts: 11 个服务器原样脚本入库(md5 对照表更新至 README);D=60.1 生产原样配方、
  E=v5 DFlash 底稿、F=PD 链四角色部署+launch+双场景压测驱动
- profiles: 新增 6 个 .env(D/E 单机 + F 四角色,均带镜像 digest
  sha256:28e0d260…,对齐 kimi3 PD 多角色先例)
- deploy/PD_CHAIN.md: 方案 F 编排手册(启动顺序 mc-master→prefill→decode→router、
  基础设施依赖表、质量门口径、拆链恢复、÷2 单机等效判决)
- platforms/patches/pro6000/glm53_pd_chain/: sglang 补丁树 vs 镜像原版 11 文件
  unified diff 快照——宿主树无 .git,此为唯一版本记录(DFlash+PP+PD 解锁全集)
- deploy/manifests/: GLM-5.3-NVFP4(47分片)/GLM-5.3-DFlash2(单分片) 权重 md5 清单
- deploy/CURRENT.md: 全集群现役状态页(2026-09-08 八机实测)
- deploy/verify_profile.sh: 防漂移核验工具(digest+参数 token 比对+端口/health,
  已在 60.1 生产容器实测 PASS)
2026-09-08 16:36:15 +08:00

92 lines
3.8 KiB
Bash
Raw Permalink 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
# verify_profile.sh —— 防漂移核验:运行中容器 vs 仓库 profile 声明
# 在目标服务器上运行(需 docker 读权限,无需 GPU。用法
# bash verify_profile.sh deploy/profiles/pro6000/glm53_nvfp4_pro6000_sglang_tp2pp4.env
# bash verify_profile.sh <profile.env> [container_name] # container_name 缺省取 profile 的 CONTAINER_NAME
# 核验项:①容器在跑 ②镜像 registry digest ③launch 参数token 级比对)④端口监听。
# PD 链角色的参数在挂载的 launch 脚本内docker Args 只有 bash /smoke_launch.sh
# 第③项自动跳过并提示改用库内脚本 md5 对比scripts/ 目录各脚本头注释有 md5
set -uo pipefail
PROFILE="$1"
[ -r "$PROFILE" ] || { echo "FATAL: 无法读取 profile: $PROFILE"; exit 2; }
# profile 是声明式清单BOOTSTRAP 行引用 ${LAUNCH_ARGS}定义在后set -u 下直接
# source 会炸;临时关 -u。source 完成后 LAUNCH_ARGS 已是全部变量展开后的实参串。
set +u
# shellcheck disable=SC1090
source "$PROFILE"
set -u
CONT="${2:-${CONTAINER_NAME:-}}"
fail=0
section() { printf '\n== %s ==\n' "$1"; }
section "容器状态"
if [ -z "$CONT" ]; then echo "FATAL: profile 未定义 CONTAINER_NAME 且未显式传入"; exit 2; fi
if docker ps --format '{{.Names}}' | grep -qx "$CONT"; then
echo "OK $CONT 在跑"
else
echo "FAIL $CONT 未在运行"; docker ps -a --filter "name=$CONT" --format '{{.Names}} {{.Status}}' | head -3
exit 1
fi
section "镜像 digest"
if [ -n "${DOCKER_IMAGE_DIGEST:-}" ]; then
# RepoDigests 在 image 对象上container 先取 image ID再 image inspect
img_id=$(docker inspect --format '{{.Image}}' "$CONT" 2>/dev/null)
repo_digests=$(docker image inspect --format '{{join .RepoDigests "\n"}}' "$img_id" 2>/dev/null)
digest_hex="${DOCKER_IMAGE_DIGEST#sha256:}"
if echo "$repo_digests" | grep -q "$digest_hex"; then
echo "OK registry digest 一致: ${DOCKER_IMAGE_DIGEST}"
elif [ "$img_id" = "sha256:${digest_hex}" ]; then
echo "OK image ID 一致: ${DOCKER_IMAGE_DIGEST}"
else
echo "FAIL digest 不一致"
echo " profile: ${DOCKER_IMAGE_DIGEST}"
echo " 实际 image ID: ${img_id}"
echo " 实际 RepoDigests: $(echo "$repo_digests" | head -2 | tr '\n' ' ')"
fail=1
fi
else
echo "SKIP profile 未定义 DOCKER_IMAGE_DIGEST"
fi
section "启动参数"
args=$(docker inspect --format '{{join .Args " "}}' "$CONT" 2>/dev/null)
if echo "$args" | grep -q launch_server; then
actual=$(echo "$args" | sed 's/.*launch_server //')
expected="${LAUNCH_ARGS:-}"
tr ' ' '\n' <<<"$expected" | sed '/^$/d' | sort > /tmp/vp_expected.$$
tr ' ' '\n' <<<"$actual" | sed '/^$/d' | sort > /tmp/vp_actual.$$
if diff -q /tmp/vp_expected.$$ /tmp/vp_actual.$$ >/dev/null; then
echo "OK 参数一致token 比对,共 $(wc -l < /tmp/vp_expected.$$) 项)"
else
echo "FAIL 参数有漂移(< profile 声明 / > 容器实际):"
diff /tmp/vp_expected.$$ /tmp/vp_actual.$$ | sed 's/^/ /'
fail=1
fi
rm -f /tmp/vp_expected.$$ /tmp/vp_actual.$$
else
echo "SKIP docker Args 为 '$args' —— 参数在挂载的 launch 脚本内"
echo " 改用库内脚本 md5 对比experiments/.../scripts/ 各脚本头注释"
fi
section "端口 ${PORT:-?}"
if [ -n "${PORT:-}" ]; then
if ss -tln | grep -q ":${PORT} "; then
echo "OK :${PORT} 在监听"
else
echo "FAIL :${PORT} 未监听"; fail=1
fi
if [ -n "${HEALTH_PATH:-}" ]; then
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:${PORT}${HEALTH_PATH}" 2>/dev/null)
[ "$code" = "200" ] && echo "OK health ${HEALTH_PATH} -> 200" || { echo "FAIL health ${HEALTH_PATH} -> ${code}"; fail=1; }
fi
else
echo "SKIP profile 未定义 PORT"
fi
echo
[ $fail -eq 0 ] && echo "VERDICT: PASS" || echo "VERDICT: DRIFT DETECTED"
exit $fail