- 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)
92 lines
3.8 KiB
Bash
92 lines
3.8 KiB
Bash
#!/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
|