Files
Deploy-Laboratory/docs/00-05-测试与验证框架.md
jack 8c43761962 feat: 按 doc_id 重组 ansible/files 与验证框架
- ansible/files 改为与文档 XX-YY 对齐的目录结构,更新相关 playbook 路径
- 新增 scripts/verify.sh 与 ansible/playbooks/verify/*.yml,移除单体 verify-matrix.yml
- 补充 docs/00-02 矩阵状态、00-05 验证框架与流程、00-04 环境与 ylc65 工作机说明
- 增加 k3s 存储准备、Longhorn、local-path 等 playbook 与辅助脚本

Made-with: Cursor
2026-03-26 07:01:14 +08:00

15 KiB
Raw Blame History

00-05-测试与验证框架(设计说明)

本页是“测试与验证框架”的设计说明,并与仓库里已落地的 scripts/verify.sh + ansible/playbooks/verify/ 对齐。

1. 为什么需要它

仓库里 docs/00-02-验证矩阵.md 目前扮演“待验证列表/状态记录”的角色,用来回答:

  • 这篇文档(XX-YY)是否已经在你的实验环境中从头到尾跑通?
  • 如果没跑通,缺口在哪里?

而“自动化执行”和“状态记录”是两件不同的事。测试框架需要把自动化执行能力,拆成可维护的小块,并通过统一的 id/索引把文档与用例关联起来。

2. 自动化验证流程(一般步骤)

下面是一条从操作者视角的通用流水线;本仓库里对应关系已写在各步括号中。

  1. 接入目标环境

    • 用 SSH 登录控制节点(或在本机配置好到控制节点的 Ansible inventory,由 Ansible 代你 SSH
    • 在仓库根(或文档约定目录)准备好代码:git pull / scp 同步等,与 docs/00-04-部署环境说明.md 一致。
    • 按需加载验证环境变量:复制并填写 scripts/.env.verify.examplescripts/.env.verify,执行前 sourceverify.sh 会自动尝试加载)。
  2. 环境与前置清理(按验证目标选择深度)

    • 基本检查kubectl get nodes、磁盘/内核版本、防火墙与文档是否一致;必要时对照 00-04
    • 轻量清理(本仓库 verify.sh 的常态):默认不卸载整个 K3s每个 verify/XX-YY.ymlteardown 阶段只删除本篇 apply 过的资源(或 gate 未执行 apply 时跳过删除),避免污染下一用例。
    • 重度清理(重装/复现安装文档时):若你要从「空机」验证 01-01整集群安装流程,才需要按文档执行 k3s-uninstall.sh、删数据目录、清 iptables 等——这与日常「矩阵逐项验收」是不同场景,不要默认混进每一次 run-all
  3. 部署

    • 推荐(本仓库):用 Ansible playbook 部署——要么是正式安装/初始化类(如 k3s-init-and-install.yml),要么是验证用例里的 kubectl apply / helm install / import_playbook
    • 文档中的 bash 一键命令:仍可按 docs/ 逐步执行;适合排障或 playbook 尚未覆盖的边角。自动化验收应尽量收敛进 ansible/playbooks/verify/*.yml,避免「文档一套、手敲一套」长期分叉。
  4. 按设计目标做断言

    • 集群侧kubectl get / describe / logskubectl rollout status、必要时看事件与 Endpoints
    • 入口侧:在控制节点或文档指定的入口上对 Service/Ingress/IngressRoutecurl(本仓库 nginx 矩阵等用响应头 X-Backend 或状态码区分路径)。
    • Helm / 存储 / 网络:按该篇文档的「预期」增查命令(如 helm listPVC Bound、跨节点 curl
    • 依赖外部云账号、NFS、ACME 邮箱等时:未满足条件可用 gate 跳过 apply并在矩阵备注中写明「未配变量未验」。
  5. 收尾与记录

    • 默认 VERIFY_TEARDOWN=1:验证通过后删除临时资源,减少对共享实验集群的干扰;调试时可设 0 保留现场。
    • 将结论写回 docs/00-02-验证矩阵.md(状态与备注),必要时更新对应 docs/XX-YY-*.md 中的命令或版本说明。
  6. 本仓库一键串联

    • 在控制节点仓库根执行:./scripts/verify.sh run-all(或 run <XX-YY>),即按矩阵顺序重复「部署 → 断言 → teardown」的自动化版本缺 playbook 会 fail-fast

2.1 局限与约定补全(建议在文档与 verify/XX-YY.yml 中写死)

下列能力 不会verify.sh 自动推断;必须在对应 docs/XX-YY-*.md 里写清「谁执行、对哪里发请求、怎样算过」,并在 playbook 里逐项实现。未写进 playbook 的步骤即视为未自动化覆盖

主题 建议约定
多节点:在哪台机器 curl 默认:在 inventory 的 k3s_server(控制节点) 上,对 集群入口 发 HTTPnginx_entry_base / http://<控制节点或 LB IP>),与「从集群外经 NodePort/主机网络进 Traefik」一致。例外(必须显式写):要验 worker 仅内网、跨节点路径、或「必须从某台 agent 访问」时,在 playbook 里对指定 host 执行 curl(或 delegate_to / 专用 play并在文档「验证命令」中写明 执行主机与目标 URL,避免隐含「任意节点等价」。
TLS / SNI 自签或跳过校验仅用于排障:curl -k验收应优先:真实证书路径下用 curl -v 看证书链;或用 curl --resolve <域名>:443:<入口IP> https://<域名>/...无 DNS 时模拟 SNI。需要时用 openssl s_client -connect host:443 -servername <域名> </dev/null 看握手。ACME 类用例依赖 公网 80/443、有效邮箱、DNS/Secretgate 跳过 apply 时,矩阵应标 ⚠️,不得记成
仅浏览器可用的 UI Traefik Dashboard OAuth、依赖 JS/CSP/WebSocket 的交互、文件上传等,curl 往往不够。约定三选一:(1) 自动化降级为只断言 IngressRoute/Deployment/Service 存在 + HTTP 非 5xx(2)00-02 备注 「UI 需手工浏览器验收」(3) 另起 CI/脚本用 headless如 Playwrightverify.sh 并列,不强行塞进 Ansible。
Helm 长耗时:超时与重试 安装/升级统一带 --wait 与合理 --timeout(大 chart 可 10m20m 量级按实际调。Ansible 侧对「Pod 未就绪」可用 until + retries + delay 轮询,避免单次 kubectl 瞬断误判。文档写清 最短等待 与失败时要看 helm status / kubectl describe / 事件。调试设 VERIFY_TEARDOWN=0 保留现场。
CI 无真集群 与实验室 verify.sh run-all 不等价。可选:kubeconform 等对清单做离线 schema有短时 apiserver 时用 kubectl apply --dry-run=server;或用 kind/k3d 起临时集群跑子集用例。应在 CI 配置或 README 中写明 「本流水线只保证 YAML/静态;矩阵级验收仍以控制节点 run-all 为准」,避免混为一谈。

原则:每篇文档至少有一句话说明 验证命令的执行位置(控制节点 / 指定 worker / 办公机经 VPN成功判据状态码、响应头、kubectl 资源相位playbook 与文档冲突时以 先修 playbook、再改文档 对齐。

3. 执行框架(与仓库一致)

此前设想的「静态层yamllint / kubeconform / ansible-lint→ 运行时 → 追溯」未纳入当前落地实现;若日后在 CI 里加格式或 schema 检查,应与 verify.sh 并列,不必塞进同一脚本。

本仓库实际验收路径只有下面几条,且都以 Ansible 为执行引擎(在控制节点上对集群下发 kubectl / helm / curl 等):

  1. docs/00-02-验证矩阵.md:列出 XX-YY 与顺序;verify.sh run-all 按文中首次出现的 XX-YY 依次执行。
  2. scripts/verify.sh:调用 ansible-playbook -i <inventory> ansible/playbooks/verify/<doc_id>.yml;缺对应 playbook 则 fail-fast
  3. ansible/playbooks/verify/<doc_id>.yml:单篇用例,通常拆成「部署 → 验证 → 清理」多个 play(默认 VERIFY_TEARDOWN=1 做 teardown
  4. 特例:无集群动作的文档可走 verify/_noop-tasks.yml(仓库路径/文件存在性);依赖 NFS、ACME、Cloudflare 等外部条件的可用 gate 跳过 applyteardown 需避免「无清单仍删」类失败(各 playbook 已按此收敛)。

真源:可部署清单以 ansible/files/ 为准;docs/XX-YY-*.md 与矩阵通过同一 doc_id 与 playbook 对齐。矩阵里的状态/备注仍建议 手工 维护(见 §7

4. 文档 id 与用例索引

约定:

  • docs/XX-YY-*.md 的文档 id 为 XX-YY(例如 02-05)。
  • 自动化用例文件名为 verify/XX-YY.yml,与 doc_id 一致即可playbook 内不必再写 YAML 字段 doc_id,除非你想自检)。
  • 框架通过 doc_id 把“文档”映射到 verify/<doc_id>.yml,从而实现按篇自动执行(verify.sh)。

这样你在 00-02 里更新状态时,不需要关心脚本内部结构;只要 id 一致就能追溯。

5. 用例数据模型(建议)

建议把用例写成“按文档 id 编排的任务集合”。在本仓库里,用例落在 ansible/playbooks/verify/<XX-YY>.yml,不再使用单体 verify-matrix.yml(已移除,避免与拆分后的 playbook 双份维护)。

  • 文档 id XX-YY → 文件 verify/XX-YY.yml
  • 每个文件内一般拆为三段(多个 play 或顺序 tasks

示例02-05./scripts/verify.sh run 02-05 执行 ansible/playbooks/verify/02-05.yml(内部 import_playbook nginx-matrix-deploy.yml,再 HTTP 校验四路径,最后 teardown02-0102-04 另有单路径 playbook便于单独调试。

每个 verify/XX-YY.yml 的典型结构为三段:

  • deploykubectl apply / helm install
  • verifykubectl rollout status / curl / assert
  • teardownkubectl delete / helm uninstall(默认执行,可用 VERIFY_TEARDOWN=0 关闭)
doc_id: "02-05"
case_id: "nginx-matrix-all"
description: "02-05 四条路径均返回 200并区分后端内容"

apply:
  paths:
    - "ansible/files/02-05-nginx-matrix/"
  strategy: "apply-r"

wait:
  namespace: "default"
  deployments:
    - "nginx-m1"
    - "nginx-m2"
    - "nginx-m3"
    - "nginx-m4"
  timeout: "180s"

http_check:
  entry_base: "http://<入口IP>"
  paths:
    - path: "/demo-m1/"
      expect_status: 200
      expect_body_contains: "Backend: M1"
    - path: "/demo-m2/"
      expect_status: 200
      expect_body_contains: "Backend: M2"

6. 执行器Executor——两类在 Ansible 中落地)

测试框架的执行器应当清晰分成两类,对应两种“被测对象”(机器 vs 集群):

6.1 Ansible 远程命令类(普通 Linux / 设备执行命令)

  • 目标:在普通 Linux/路由/设备上通过 ssh 执行命令,并做断言(例如 exit_codestdout_contains/regexfile_exists)。
  • 不强制要求在这类执行器里做 HTTP/curl 校验HTTP/服务可用性校验归到 K3s 类用例。

落地方式Ansible 的 command/shell + assertinventory 决定 SSH 目标与用户/密钥)。

6.2 Ansible K3s 集群类(部署 + 结果校验 + 可选清理)

  • 目标:对 K3s 集群做 apply / wait / check / http_check(可选),并支持可选 teardown/delete
  • 执行位置分两种:
    • 本机直接 kubectl
    • kubectl 需要通过 SSH 在控制节点执行(复用你现有的 .env.verify 变量语义)

落地方式Ansible 在控制节点(如 ylc61执行 kubectl / helm / curl,多个 play 顺序执行。默认策略:验证完成后 执行 teardown(清理部署),可通过 VERIFY_TEARDOWN=0 关闭。

7. 状态记录与写回策略

你已经在 docs/00-02-验证矩阵.md 里定义了状态含义(未验证/部分验证/已验证)。

建议未来的写回策略分两步:

  • 首先:仍然由你手工更新 00-02(减少自动化失败导致的误写)
  • 之后:如果要自动写回,则需要明确“失败判定标准、覆盖范围、并发策略”,避免多个执行器同时写同一条状态。

8. 与旧自动化的关系

  • docs/00-02-验证矩阵.md 不承担执行细节,只作待验证列表与状态记录
  • 自动化执行以 scripts/verify.shansible/playbooks/verify/*.yml 为准;本页描述其约定与扩展方式

9. 可选扩展(未落地)

当前「一篇文档 → 一个 verify/XX-YY.yml」在规模小时最简单:入口仍是 scripts/verify.sh,不必为了「架构感」提前建一堆目录。当出现下面任一情况时,再考虑本节里的拆法即可。

9.1 何时值得拆

  • 重复:多个 playbook 里出现相同的 kubectl rollout statuscurl 重试、gate + teardown 模板,改一处要改十处。
  • 体积:单个 XX-YY.yml 过长,难以一眼看清「本篇到底验了什么」。
  • 复用非 Ansible 逻辑:例如要在本机做纯文本处理、复杂拼接,再交给 Ansible这类少量逻辑可以放在 shell大量仍建议用 Ansibleinventory、变量、幂等已有约定

9.2 Ansible 侧:角色与 include_tasks(优先)

与正式部署 playbook 一样,验证逻辑优先留在 Ansible 生态里拆:

  • include_tasksimport_tasks:把「等 Deployment」「带重试的 HTTP 检查」「安全 delete」抽成 ansible/playbooks/verify/_*.yml 小文件,由各 XX-YY.yml 引用。
  • Role(例如 ansible/roles/k3s_verify_http/):当同一套「变量约定 + 多 task」在多篇文档复用时用 role 比复制粘贴更清晰;verify.sh 不需要改,仍只调用 verify/XX-YY.yml,由该文件 roles:import_role 即可。

原则:verify.sh 只认 verify/<doc_id>.yml 这一层文件名;底下怎么组织 include/role 是内部重构。

9.3 scripts/lib/(次要)

适合只放 bash 层的薄工具:解析矩阵、拼 ansible-playbook 参数、统一日志格式等。若把「怎么 curl」「怎么 kubectl wait」写进大量 shell容易和 inventory、sudo、KUBECONFIG 两套路径打架,一般不如 Ansible task

9.4 单独的 tests/ 目录(与现框架并列)

若将来引入 非 Ansible 的测试运行器(例如用编程语言写契约测试、或只跑静态检查),可以建 tests/ 存放用例与配置,由 CI 或另一条脚本 调用;它与 verify.sh并列流水线,而不是替换关系:

  • 矩阵验收 / 真机集群路径:仍以 verify.sh + verify/*.yml 为准。
  • PR 上的快速反馈:可对 ansible/files/**/*.yaml 跑 yamllint、kubeconform、kubectl apply --dry-run=server(需集群凭据时再决定挂不挂 CI

这样不会出现「同一篇文档到底以哪套测试为准」的模糊地带:文档级约定验收看矩阵 + verify playbook代码库卫生看 CI。

9.5 静态检查(再次强调)

yamllint、ansible-lint、schema 校验等 不放进 verify.sh 亦可:在 GitHub Actions / 本地 pre-commit 里单独跑即可。与 §3 一致——与运行时验证 并列,互不嵌套。