- 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
15 KiB
00-05-测试与验证框架(设计说明)
本页是“测试与验证框架”的设计说明,并与仓库里已落地的
scripts/verify.sh+ansible/playbooks/verify/对齐。
1. 为什么需要它
仓库里 docs/00-02-验证矩阵.md 目前扮演“待验证列表/状态记录”的角色,用来回答:
- 这篇文档(
XX-YY)是否已经在你的实验环境中从头到尾跑通? - 如果没跑通,缺口在哪里?
而“自动化执行”和“状态记录”是两件不同的事。测试框架需要把自动化执行能力,拆成可维护的小块,并通过统一的 id/索引把文档与用例关联起来。
2. 自动化验证流程(一般步骤)
下面是一条从操作者视角的通用流水线;本仓库里对应关系已写在各步括号中。
-
接入目标环境
- 用 SSH 登录控制节点(或在本机配置好到控制节点的 Ansible
inventory,由 Ansible 代你 SSH)。 - 在仓库根(或文档约定目录)准备好代码:
git pull/scp同步等,与docs/00-04-部署环境说明.md一致。 - 按需加载验证环境变量:复制并填写
scripts/.env.verify.example为scripts/.env.verify,执行前source(verify.sh会自动尝试加载)。
- 用 SSH 登录控制节点(或在本机配置好到控制节点的 Ansible
-
环境与前置清理(按验证目标选择深度)
- 基本检查:
kubectl get nodes、磁盘/内核版本、防火墙与文档是否一致;必要时对照00-04。 - 轻量清理(本仓库
verify.sh的常态):默认不卸载整个 K3s;每个verify/XX-YY.yml在 teardown 阶段只删除本篇 apply 过的资源(或 gate 未执行 apply 时跳过删除),避免污染下一用例。 - 重度清理(重装/复现安装文档时):若你要从「空机」验证
01-01等整集群安装流程,才需要按文档执行k3s-uninstall.sh、删数据目录、清 iptables 等——这与日常「矩阵逐项验收」是不同场景,不要默认混进每一次run-all。
- 基本检查:
-
部署
- 推荐(本仓库):用 Ansible playbook 部署——要么是正式安装/初始化类(如
k3s-init-and-install.yml),要么是验证用例里的kubectl apply/helm install/import_playbook。 - 文档中的 bash 一键命令:仍可按
docs/逐步执行;适合排障或 playbook 尚未覆盖的边角。自动化验收应尽量收敛进ansible/playbooks/verify/*.yml,避免「文档一套、手敲一套」长期分叉。
- 推荐(本仓库):用 Ansible playbook 部署——要么是正式安装/初始化类(如
-
按设计目标做断言
- 集群侧:
kubectl get/describe/logs、kubectl rollout status、必要时看事件与Endpoints。 - 入口侧:在控制节点或文档指定的入口上对
Service/Ingress/IngressRoute做curl(本仓库 nginx 矩阵等用响应头X-Backend或状态码区分路径)。 - Helm / 存储 / 网络:按该篇文档的「预期」增查命令(如
helm list、PVC Bound、跨节点 curl)。 - 依赖外部云账号、NFS、ACME 邮箱等时:未满足条件可用 gate 跳过 apply,并在矩阵备注中写明「未配变量未验」。
- 集群侧:
-
收尾与记录
- 默认
VERIFY_TEARDOWN=1:验证通过后删除临时资源,减少对共享实验集群的干扰;调试时可设0保留现场。 - 将结论写回
docs/00-02-验证矩阵.md(状态与备注),必要时更新对应docs/XX-YY-*.md中的命令或版本说明。
- 默认
-
本仓库一键串联
- 在控制节点仓库根执行:
./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(控制节点) 上,对 集群入口 发 HTTP(如 nginx_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/Secret;gate 跳过 apply 时,矩阵应标 ⚠️,不得记成 ✅。 |
| 仅浏览器可用的 UI | Traefik Dashboard OAuth、依赖 JS/CSP/WebSocket 的交互、文件上传等,curl 往往不够。约定三选一:(1) 自动化降级为只断言 IngressRoute/Deployment/Service 存在 + HTTP 非 5xx;(2) 在 00-02 备注 「UI 需手工浏览器验收」;(3) 另起 CI/脚本用 headless(如 Playwright),与 verify.sh 并列,不强行塞进 Ansible。 |
| Helm 长耗时:超时与重试 | 安装/升级统一带 --wait 与合理 --timeout(大 chart 可 10m~20m 量级,按实际调)。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 等):
docs/00-02-验证矩阵.md:列出XX-YY与顺序;verify.sh run-all按文中首次出现的XX-YY依次执行。scripts/verify.sh:调用ansible-playbook -i <inventory> ansible/playbooks/verify/<doc_id>.yml;缺对应 playbook 则 fail-fast。ansible/playbooks/verify/<doc_id>.yml:单篇用例,通常拆成「部署 → 验证 → 清理」多个 play(默认VERIFY_TEARDOWN=1做 teardown)。- 特例:无集群动作的文档可走
verify/_noop-tasks.yml(仓库路径/文件存在性);依赖 NFS、ACME、Cloudflare 等外部条件的可用 gate 跳过 apply,teardown 需避免「无清单仍删」类失败(各 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 校验四路径,最后 teardown)。02-01~02-04 另有单路径 playbook,便于单独调试。
每个 verify/XX-YY.yml 的典型结构为三段:
- deploy:
kubectl apply/helm install - verify:
kubectl rollout status/curl/assert - teardown:
kubectl 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_code、stdout_contains/regex、file_exists)。 - 不强制要求在这类执行器里做 HTTP/curl 校验;HTTP/服务可用性校验归到 K3s 类用例。
落地方式:Ansible 的 command/shell + assert(inventory 决定 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.sh与ansible/playbooks/verify/*.yml为准;本页描述其约定与扩展方式
9. 可选扩展(未落地)
当前「一篇文档 → 一个 verify/XX-YY.yml」在规模小时最简单:入口仍是 scripts/verify.sh,不必为了「架构感」提前建一堆目录。当出现下面任一情况时,再考虑本节里的拆法即可。
9.1 何时值得拆
- 重复:多个 playbook 里出现相同的
kubectl rollout status、curl重试、gate + teardown 模板,改一处要改十处。 - 体积:单个
XX-YY.yml过长,难以一眼看清「本篇到底验了什么」。 - 复用非 Ansible 逻辑:例如要在本机做纯文本处理、复杂拼接,再交给 Ansible;这类少量逻辑可以放在 shell,大量仍建议用 Ansible(inventory、变量、幂等已有约定)。
9.2 Ansible 侧:角色与 include_tasks(优先)
与正式部署 playbook 一样,验证逻辑优先留在 Ansible 生态里拆:
include_tasks或import_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 一致——与运行时验证 并列,互不嵌套。