已开启
docs(preflight): add unified preflight design #210
docs(preflight): add unified preflight design #210
已开启
thyzfmh创建于 7月29日
8 个文件变更+1694-3
@@ -0,0 +1,213 @@
1+# cluster-create 阶段检查项提案
2+ 
3+## 1. 阶段描述
4+ 
5+`bke preflight cluster-create` 在执行 `bke cluster create` 前,使用相同的 cluster/nodes 文件和
6+管理集群 kubeconfig,检查输入、管理集群只读依赖、目标节点、角色端口和安装来源。
7+ 
8+命令只读解析文件、读取管理集群并通过 SSH 采集目标节点事实,不创建或修改 Kubernetes 资源,
9+不上传脚本,不执行安装和清理。
10+ 
11+### 1.1 目标
12+ 
13+- 单次读取并严格解析 cluster/nodes,复用 Provider 的纯默认化和本地校验语义。
14+- 根据最终节点、角色、端口和来源动态生成 OperationPlan 和 RuleBinding。
15+- 准确区分输入、管理集群、SSH 网络、认证、权限和环境不满足。
16+- 根依赖失败后停止下游探测,避免一个问题扩散成多条 FAIL。
17+- YAML 错误和规则结果均尽可能定位到具体字段、节点、端口、路径或来源。
18+ 
19+### 1.2 输入与优先级
20+ 
21+```bash
22+bke --kubeconfig /path/to/management.kubeconfig \
23+ preflight cluster-create \
24+ --file ./cluster.yaml \
25+ --nodes ./nodes.yaml
26+ 
27+bke --kubeconfig /path/to/management.kubeconfig \
28+ preflight cluster-create \
29+ --preflight-config ./preflight.yaml \
30+ --file ./cluster.yaml --nodes ./nodes.yaml \
31+ --output json --output-file report.json
32+```
33+ 
34+v1 不提供 `--request`。运行值优先级为:cluster/nodes 显式字段或管理集群 Provider 值 > 外部
35+policy fallback > 内嵌默认 policy。policy 不修改输入对象或后续安装参数。
36+ 
37+## 2. 计划与依赖设计
38+ 
39+```text
40+cluster.yaml + nodes.yaml + management kubeconfig
41+ → 严格解析和 Provider 纯默认化/校验
42+ → 管理集群只读 defaults/facts
43+ → OperationPlan(cluster、nodes、values、sources)
44+ → RuleBinding
45+ → SDK Collector / CEL / Report
46+```
47+ 
48+Plan Subject 必须稳定标识 cluster 和每个目标节点。管理集群事实绑定到 `cluster` 范围,并通过
49+Evidence locator 标识 API、CRD、Secret 或字段;不建立独立的 management Subject。节点地址、SSH
50+端口、角色、业务端口、来源和非敏感 metadata 进入 PlanHash;密码、Token、私钥和完整 kubeconfig
51+不得进入。
52+ 
53+主要根依赖:
54+ 
55+```text
56+Management API → Discovery → BKECluster/BKENode CRD
57+Management API → Secret GET → Secret data → kubeconfig parse → source endpoint
58+SSH TCP transport → SSH auth → root/sudo privilege → 节点事实、端口、来源和 customChecks
59+```
60+ 
61+管理默认值或客户端初始化失败不得静默回退到可能错误的静态值,也不得将远端事实路由到本地
62+Collector。`Applicable=false` 不实例化;只有适用项被依赖、超时或取消阻塞时才产生 SKIP。
63+ 
64+## 3. 固定检查项
65+ 
66+固定目录包含46个模板。`来源`为 Bundle Source ID,并由 SourceLock 映射到固定 repo、revision、
67+path、locator 和 sourceURL。
68+`CLUSTER-HA-COLOCATE` 使用 `WARNING/WARN` 外,其余固定模板使用 `ERROR/BLOCK`
69+ 
70+### 3.1 输入唯一性与拓扑(6项)
71+ 
72+| # | Rule ID | 检查对象 | 期望值/判断 | 来源 |
73+|---:|---|---|---|---|
74+| 1 | `CLUSTER-UNIQUE-IP` | 节点 IP | 非空 IP 不重复 | `CAPBKE-VALIDATION` |
75+| 2 | `CLUSTER-UNIQUE-HOSTNAME` | 节点 hostname | 仅非空 hostname 不重复;空值不失败 | `CAPBKE-VALIDATION` |
76+| 3 | `CLUSTER-TOPO-MASTER` | master 数量 | 不少于1 | `CAPBKE-VALIDATION` |
77+| 4 | `CLUSTER-TOPO-MASTER-ODD` | master 数量 | 为奇数 | `CAPBKE-VALIDATION` |
78+| 5 | `CLUSTER-TOPO-ETCD` | etcd 数量 | 不少于1 | `CAPBKE-VALIDATION` |
79+| 6 | `CLUSTER-TOPO-WORKER` | worker 能力数量 | 不少于1;master+worker 计入 worker | `CAPBKE-VALIDATION` |
80+ 
81+不存在 `CLUSTER-UNIQUE-NAME`。Provider 没有节点对象名称唯一性约束时,不增加该门禁。
82+ 
83+### 3.2 管理集群与本地输入(10项)
84+ 
85+| # | Rule ID | 检查对象 | 期望值/判断 | 依赖 | 来源 |
86+|---:|---|---|---|---|---|
87+| 7 | `CLUSTER-MGMT-API` | 管理集群 API | 可连接 | 根依赖 | `CAPBKE-VALIDATION` |
88+| 8 | `CLUSTER-MGMT-DISCOVERY` | API Discovery | 可读取 | API | `CAPBKE-VALIDATION` |
89+| 9 | `CLUSTER-MGMT-CRD-CLUSTER` | BKECluster CRD | 已注册 | Discovery | `CAPBKE-VALIDATION` |
90+| 10 | `CLUSTER-MGMT-CRD-NODE` | BKENode CRD | 已注册 | Discovery | `CAPBKE-VALIDATION` |
91+| 11 | `CLUSTER-MGMT-AGENT-KUBECONFIG-GET` | `kube-system/localkubeconfig` | Secret 可 GET | API | `CAPBKE-VALIDATION` |
92+| 12 | `CLUSTER-MGMT-AGENT-KUBECONFIG-DATA` | Secret 数据 | 目标键非空 | Secret GET | `CAPBKE-VALIDATION` |
93+| 13 | `CLUSTER-MGMT-AGENT-KUBECONFIG-PARSE` | Agent kubeconfig | 可解析 | Secret data | `CAPBKE-VALIDATION` |
94+| 14 | `CLUSTER-MGMT-AGENT-KUBECONFIG-SOURCE` | kubeconfig server | endpoint 语法有效 | kubeconfig parse | `CAPBKE-VALIDATION` |
95+| 15 | `CLUSTER-MGMT-LOCAL-CLUSTER` | 本地 BKECluster 输入 | schema/业务校验通过 | 独立 | `CAPBKE-VALIDATION` |
96+| 16 | `CLUSTER-MGMT-LOCAL-NODE` | 本地 BKENode 输入 | schema/业务校验通过 | 独立 | `CAPBKE-VALIDATION` |
97+ 
98+### 3.3 本地路径、网络、HA 和 addon(9项)
99+ 
100+| # | Rule ID | 检查对象 | 期望值/判断 | 条件 | 来源 |
101+|---:|---|---|---|---|---|
102+| 17 | `CLUSTER-LOCAL-PATH-CREATE` | 集群输出路径 | 已存在或父路径允许创建 | 始终 | `CAPBKE-VALIDATION` |
103+| 18 | `CLUSTER-LOCAL-PATH-ACCESS` | 集群输出路径 | 可访问 | 始终 | `CAPBKE-VALIDATION` |
104+| 19 | `CLUSTER-LOCAL-PATH-MOUNT` | 输出路径挂载点 | 非只读挂载 | 始终 | `CAPBKE-VALIDATION` |
105+| 20 | `CLUSTER-NET-POD-CIDR` | Pod subnet | CIDR 语法有效 | 已配置 | `CAPBKE-VALIDATION` |
106+| 21 | `CLUSTER-NET-SERVICE-CIDR` | Service subnet | CIDR 语法有效 | 已配置 | `CAPBKE-VALIDATION` |
107+| 22 | `CLUSTER-HA-COLOCATE` | bootstrap 与 HA master | 可证明同一稳定节点时提示风险 | WARNING;master>1 且可识别 bootstrap | `CAPBKE-VALIDATION` |
108+| 23 | `CLUSTER-REF-VERSION` | Provider/版本引用 | 属于当前发布支持范围 | 始终 | `CAPBKE-VALIDATION` |
109+| 24 | `CLUSTER-ADDON-CLOSURE` | addon 依赖 | 依赖闭包完整 | 按 addon | `CAPBKE-VALIDATION` |
110+| 25 | `CLUSTER-ADDON-SOURCE` | addon 来源配置 | 必需来源信息配置完整 | 按 addon | `CAPBKE-VALIDATION` |
111+ 
112+CIDR 本期只校验语法,不推测网段重叠。`CLUSTER-ADDON-SOURCE` 只检查配置完整,不表示网络可达;
113+来源连通性由 `CLUSTER-SRC-REACHABLE` 负责。普通 master+worker AIO 不等于 bootstrap 共部署。v1
114+生产 Host 当前不提供可独立证明的 bootstrap 节点映射,因此不实例化 HA 告警;只有后续 Host 能
115+可信设置 `BootstrapNodeID` 时,才按本表条件实例化。
116+ 
117+`CLUSTER-HA-COLOCATE``CAPBKE-VALIDATION` 只追溯 Provider 的角色和 HA 拓扑语义;该规则不表示
118+Provider 禁止共部署,其 WARNING 策略及“必须先证明 bootstrap 身份”的限制由本提案定义。
119+ 
120+### 3.4 SSH、权限、资源与平台(10项)
121+ 
122+| # | Rule ID | 检查对象 | 期望值/判断 | 依赖 | 来源 |
123+|---:|---|---|---|---|---|
124+| 26 | `CLUSTER-SSH-TRANSPORT` | SSH host:port | 纯 TCP 可连接 | 根依赖 | `DOC-QUICKSTART` |
125+| 27 | `CLUSTER-SSH-AUTH` | SSH 认证 | 最终凭据可建立会话 | transport | `DOC-QUICKSTART` |
126+| 28 | `CLUSTER-SSH-PRIVILEGE` | 执行权限 | root 或无交互 sudo 可用 | auth | `DOC-QUICKSTART` |
127+| 29 | `CLUSTER-AGENT-SYSTEMD` | systemd | 可用 | privilege | `DOC-QUICKSTART` |
128+| 30 | `CLUSTER-RES-CPU` | 逻辑 CPU | 默认不少于8核 | privilege | `DOC-QUICKSTART` |
129+| 31 | `CLUSTER-RES-MEMORY` | 可用内存 | 默认不少于16 GiB | privilege | `DOC-QUICKSTART` |
130+| 32 | `CLUSTER-RES-SYSTEM-DISK` | 系统盘容量 | 默认不少于100 GiB | privilege | `DOC-QUICKSTART` |
131+| 33 | `CLUSTER-PLAT-OS` | OS | Linux | privilege | `DOC-QUICKSTART` |
132+| 34 | `CLUSTER-PLAT-DISTRO` | 发行版 | 命中当前策略平台矩阵 | privilege | `DOC-QUICKSTART` |
133+| 35 | `CLUSTER-PLAT-KERNEL` | 内核 | 命中发行版对应内核前缀 | privilege | `DOC-QUICKSTART` |
134+ 
135+transport 只做 TCP;认证必须单独建立 SSH 会话。凭据错误不能误报为网络失败。v1 Host 不校验
136+SSH host key,只能证明会话建立,不能描述为已完成目标节点身份或 host-key 信任校验。
137+ 
138+### 3.5 角色端口和来源(11项)
139+ 
140+| # | Rule ID | 检查对象 | 期望值/判断 | 角色/条件 | 来源 |
141+|---:|---|---|---|---|---|
142+| 36 | `CLUSTER-PORT-APISERVER` | kube-apiserver | 实际端口空闲,默认6443/TCP | master | `MANIFEST` |
143+| 37 | `CLUSTER-PORT-CONTROLLER` | controller-manager | 10257/TCP 空闲 | master | `MANIFEST` |
144+| 38 | `CLUSTER-PORT-SCHEDULER` | scheduler | 10259/TCP 空闲 | master | `MANIFEST` |
145+| 39 | `CLUSTER-PORT-LOCAL-HA` | 本地 HA | 36443/TCP 空闲 | 多 master | `MANIFEST` |
146+| 40 | `CLUSTER-PORT-ETCD-CLIENT` | etcd client | 2379/TCP 空闲 | etcd | `MANIFEST` |
147+| 41 | `CLUSTER-PORT-ETCD-PEER` | etcd peer | 2380/TCP 空闲 | etcd | `MANIFEST` |
148+| 42 | `CLUSTER-PORT-ETCD-METRICS` | etcd metrics | 2381/TCP 空闲 | etcd | `MANIFEST` |
149+| 43 | `CLUSTER-PORT-KUBELET-SECURE` | kubelet secure | 10250/TCP 空闲 | master 或 worker | `MANIFEST` |
150+| 44 | `CLUSTER-PORT-KUBELET-HEALTH` | kubelet health | 10248/TCP 空闲 | master 或 worker | `MANIFEST` |
151+| 45 | `CLUSTER-PORT-BKEAGENT` | BKEAgent | 58080/TCP 空闲 | 所有目标节点 | `MANIFEST` |
152+| 46 | `CLUSTER-SRC-REACHABLE` | 节点到实际安装来源 | 可建立脱敏 host:port TCP 连接 | 每节点、每来源 | `DOC-QUICKSTART` |
153+ 
154+远端来源使用已有 SSH 连接的 `direct-tcpip` 通道,不依赖节点安装 curl 或 nc,也不执行 HTTP、
155+TLS、认证和对象下载。
156+ 
157+### 3.6 自定义检查(0..64项)
158+ 
159+cluster-create 自定义检查位于 `operations.clusterCreate.customChecks`,按 roles 展开到匹配节点;
160+roles 为空或 `[all]` 时覆盖所有目标节点:
161+ 
162+| Rule ID | Collector | 判断 | 固定依赖 | 来源 |
163+|---|---|---|---|---|
164+| `CONFIG-CLUSTER-CREATE-CUSTOM-<KEY>` | `fileContent` 或受控 `exec` | `expression(actual)` 必须为 true | `CLUSTER-SSH-PRIVILEGE` | `RUNTIME-PREFLIGHT-CONFIG` |
165+ 
166+脚本必须预装在节点,不上传、不下载、不隐式 sudo。用户不配置 digest,由框架按节点记录观测摘要。
167+ 
168+## 4. 输入错误与报告
169+ 
170+- cluster/nodes 必须是普通文件,分别受大小限制并严格解析。
171+- 未知字段和类型错误使用路径式字段,如
172+ `cluster.spec.clusterConfig.cluster.networking.podSubnet``nodes[0].spec.ip`
173+- YAML 语法错误无法恢复字段路径时保留文件名、行号和解析详情。
174+- Provider 本地业务校验结果应携带可确定的同类字段 locator。
175+- 缺少文件、解析失败或无法形成计划时显示“前置检查未启动”,不产生伪环境 FAIL。
176+ 
177+目标列必须说明“哪个节点的什么”,例如:
178+ 
179+- `cluster / management Secret kube-system/localkubeconfig`
180+- `cluster.yaml / spec.clusterConfig.cluster.networking.podSubnet`
181+- `master-01 (192.0.2.10:22) / SSH authentication`
182+- `master-01 (192.0.2.10) / TCP 6443`
183+- `master-01 (192.0.2.10) / Image repository example.com:443`
184+ 
185+## 5. 只读、安全与质量属性
186+ 
187+- Kubernetes 只允许 Discovery、GET 和 LIST,不得 CREATE、UPDATE、PATCH、DELETE 或 server-side dry-run。
188+- SSH 固定规则只使用 allowlist 只读命令;凭据不进入 Plan、Fact、Evidence、Report 或日志。
189+- 输出路径检查不创建目录或测试文件。
190+- 总体 context 覆盖 management defaults、客户端、Adapter、SSH、TCP、SDK 和渲染前阶段。
191+- 同一 `(subject,factKey)` 只采集一次;并发不影响结果顺序和计数。
192+- 连接、认证、权限、超时和业务不满足必须保持不同错误归属。
193+ 
194+## 6. 测试与验收
195+ 
196+必须覆盖:
197+ 
198+- cluster/nodes 严格解析、字段路径、文件行号、Provider 默认化和优先级。
199+- 空 hostname、重复 hostname/IP、普通 AIO、Host 未提供 bootstrap 映射时不实例化,以及 Adapter
200+ 契约中可证明 bootstrap+HA 的正反场景。
201+- management API/Discovery/CRD 与 Secret/kubeconfig 两条依赖链。
202+- SSH transport PASS/auth FAIL、privilege FAIL 和下游 SKIP。
203+- 每个角色端口、实际端口覆盖、同节点多角色去重和多来源展开。
204+- 远端来源使用 direct-tcpip,不执行 HTTP 或依赖 curl/nc。
205+- custom fileContent/exec 的角色、依赖、类型、权限、超限、摘要和脱敏。
206+- timeout/cancel、text/JSON、窄终端、中英文宽度和 Summary 算术一致。
207+- Linux 真实 CLI、SSH 和管理集群 Kubernetes 只读链路;fake collector 测试不能替代真实 E2E。
208+ 
209+## 7. 参考资料
210+ 
211+- [openFuyao 统一前置检查提案](./openFuyao统一前置检查提案.md)
212+- [校验框架 SDK 提案](./校验框架SDK提案.md)
213+- [preflight-bundle-gen 提案](./preflight-bundle-gen提案.md)
@@ -0,0 +1,170 @@
1+# init 阶段检查项提案
2+ 
3+## 1. 阶段描述
4+ 
5+`bke preflight init` 在执行 `bke init` 前,以相同业务参数检查引导节点是否满足初始化条件。该命令
6+只生成计划、采集只读事实并输出报告,不执行 K3s、仓库、Console 或其他组件的安装、修复和清理。
7+ 
8+### 1.1 目标
9+ 
10+-`bke init` 共享 FlagSpec、纯 Resolver 和 Validate,保持参数、默认值和互斥关系一致。
11+- 使用最终解析值检查平台、资源、路径、端口、来源、离线制品和自定义仓库。
12+- 仅实例化当前输入适用的规则,不用“不适用”或“无法确认”制造告警。
13+- 对文件、来源和证书建立真实依赖,一个根因只显示一次。
14+- 报告明确引导节点、端口、路径、来源、期望、实际和修复动作。
15+ 
16+### 1.2 输入与优先级
17+ 
18+```bash
19+bke preflight init --hostIP 192.0.2.10 --installConsole=false
20+ 
21+bke preflight init \
22+ --preflight-config ./preflight.yaml \
23+ --hostIP 192.0.2.10 \
24+ --output json --output-file report.json
25+```
26+ 
27+v1 不提供 `--request`。init 业务值优先级为:显式 CLI 或业务配置值 > 外部 policy fallback >
28+内嵌默认 policy。外部 policy 只改变本次检查,不回写后续 `bke init` 的安装参数。
29+ 
30+## 2. 计划与实例化设计
31+ 
32+Host Adapter 将解析后的 init 输入转换为通用 OperationPlan:
33+ 
34+```text
35+init CLI flags
36+ → 共享 Resolver / Validate
37+ → AdapterInput
38+ → OperationPlan(bootstrap、values、sources)
39+ → RuleBinding
40+ → SDK Collector / CEL / Report
41+```
42+ 
43+Plan 只保存完成检查所需的非敏感最终值。用户名、密码、Token、私钥和完整 kubeconfig 不得进入
44+PlanHash、Fact、Evidence 或 Report。
45+ 
46+规则适用条件:
47+ 
48+- 平台、资源、工具、Workspace 和基础端口绑定到 bootstrap。
49+- Console 端口只在 `installConsole=true` 时实例化。
50+- 本地 NTP 端口只在最终计划确认本机提供 NTP 时实例化;外部 NTP 不检查 UDP 123。
51+- 来源规则按本次 init 实际使用的来源逐项实例化。
52+- 离线制品规则只在配置离线包时实例化。
53+- 自定义仓库和 CA 规则只在对应参数存在时实例化。
54+- 当前 init 输入不能可靠证明 bootstrap 与目标集群共部署,因此 `INIT-COLOCATE` 不实例化。
55+- `Applicable=false` 不产生 Result;只有适用项被依赖、超时或取消阻塞时才产生 SKIP。
56+ 
57+## 3. 固定检查项
58+ 
59+`来源`为 Bundle Source ID,并由 SourceLock 映射到固定 repo、revision、path、locator 和
60+sourceURL。固定目录包含27个模板,但每次运行的实际实例数由输入和适用条件决定。
61+`INIT-COLOCATE` 使用 `WARNING/WARN` 外,其余固定模板使用 `ERROR/BLOCK`
62+ 
63+### 3.1 执行环境与平台(8项)
64+ 
65+| # | Rule ID | 检查对象 | 期望值/判断 | 条件 | 来源 |
66+|---:|---|---|---|---|---|
67+| 1 | `INIT-EXEC-001` | 本地执行身份 | UID 为0 | 始终 | `RELEASE-PROFILE` |
68+| 2 | `INIT-PLAT-OS` | 引导节点 OS | Linux | 始终 | `RELEASE-PROFILE` |
69+| 3 | `INIT-PLAT-DISTRO` | 发行版 | 命中当前策略平台矩阵 | 始终 | `RELEASE-PROFILE` |
70+| 4 | `INIT-PLAT-KERNEL` | 内核 | 命中发行版对应内核前缀 | 始终 | `RELEASE-PROFILE` |
71+| 5 | `INIT-PLAT-ARCH` | 架构 | amd64 或 arm64 | 始终 | `RELEASE-PROFILE` |
72+| 6 | `INIT-RES-CPU` | 逻辑 CPU | 默认不少于2核 | 始终 | `RELEASE-PROFILE` |
73+| 7 | `INIT-RES-MEMORY` | 可用内存 | 默认不少于4 GiB | 始终 | `RELEASE-PROFILE` |
74+| 8 | `INIT-RES-SYSTEM-DISK` | 系统盘容量 | 默认不少于100 GiB | 始终 | `RELEASE-PROFILE` |
75+ 
76+### 3.2 工具、路径和端口(10项)
77+ 
78+| # | Rule ID | 检查对象 | 期望值/判断 | 条件 | 来源 |
79+|---:|---|---|---|---|---|
80+| 9 | `INIT-TOOL-TAR` | `tar` | PATH 中存在且可执行 | 始终 | `RELEASE-PROFILE` |
81+| 10 | `INIT-TOOL-SYSTEMCTL` | `systemctl` | PATH 中存在且可执行 | 始终 | `RELEASE-PROFILE` |
82+| 11 | `INIT-PATH-CREATE` | 最终 Workspace | 已存在或父路径允许创建 | 始终 | `RELEASE-PROFILE` |
83+| 12 | `INIT-PATH-MOUNT` | Workspace 挂载点 | 非只读挂载 | 始终 | `RELEASE-PROFILE` |
84+| 13 | `INIT-PORT-K8S` | Kubernetes 服务端口 | 实际端口空闲,默认36443/TCP | 始终 | `BKE-INIT-PORTS` |
85+| 14 | `INIT-PORT-REGISTRY` | 镜像服务端口 | 实际端口空闲,默认40443/TCP | 始终 | `BKE-INIT-PORTS` |
86+| 15 | `INIT-PORT-CHART` | Chart 服务端口 | 实际端口空闲,默认38080/TCP | 始终 | `BKE-INIT-PORTS` |
87+| 16 | `INIT-PORT-HTTP` | 软件包服务端口 | 实际端口空闲,默认40080/TCP | 始终 | `BKE-INIT-PORTS` |
88+| 17 | `INIT-PORT-CONSOLE` | Console 端口 | 实际端口空闲,默认30010/TCP | Console 启用 | `BKE-INIT-PORTS` |
89+| 18 | `INIT-PORT-NTP` | 本地 NTP 端口 | 实际端口空闲,默认123/UDP | 本机提供 NTP | `RELEASE-PROFILE` |
90+ 
91+路径检查只读取路径和挂载信息,不创建目录或测试文件;端口检查使用最终业务值。
92+ 
93+### 3.3 来源、离线制品和自定义仓库(8项)
94+ 
95+| # | Rule ID | 检查对象 | 期望值/判断 | 条件 | 来源 |
96+|---:|---|---|---|---|---|
97+| 19 | `INIT-SRC-REACHABLE` | 本次实际安装来源 | 可建立到脱敏 host:port 的 TCP 连接 | 按来源实例化 | `BKE-INIT-EXEC` |
98+| 20 | `INIT-OFFLINE-EXISTS` | 离线制品路径 | 文件存在 | 离线模式 | `DOC-INTEGRITY` |
99+| 21 | `INIT-OFFLINE-READ` | 离线制品路径 | 文件可读 | 依赖存在 | `DOC-INTEGRITY` |
100+| 22 | `INIT-OFFLINE-FORMAT` | 离线制品格式 | tar、tar.gz 或 tgz | 依赖可读 | `DOC-INTEGRITY` |
101+| 23 | `INIT-REPO-URL` | 自定义仓库地址 | URL、域名/IP 和端口可解析 | 已配置仓库 | `RELEASE-PROFILE` |
102+| 24 | `INIT-REPO-CA-EXISTS` | 自定义 CA 文件 | 文件存在 | 已配置 CA | `RELEASE-PROFILE` |
103+| 25 | `INIT-REPO-CA-READ` | 自定义 CA 文件 | 文件可读 | 依赖存在 | `RELEASE-PROFILE` |
104+| 26 | `INIT-REPO-CA-PARSE` | 自定义 CA 内容 | 可解析为 PEM X.509 证书 | 依赖可读 | `RELEASE-PROFILE` |
105+ 
106+来源检查只证明 TCP 连通,不执行 HTTP、TLS、认证或对象下载。失败建议不得编造密码、证书或镜像
107+tag 等未被探测的原因。
108+ 
109+### 3.4 共部署模板(1项)
110+ 
111+| # | Rule ID | 检查对象 | 期望值/判断 | 级别与条件 | 来源 |
112+|---:|---|---|---|---|---|
113+| 27 | `INIT-COLOCATE` | bootstrap 与集群角色关系 | 可证明共部署时提示容量和故障域风险 | WARNING;当前普通 init 不实例化 | `DOC-QUICKSTART` |
114+ 
115+### 3.5 自定义检查(0..64项)
116+ 
117+init 自定义检查位于 `operations.init.customChecks`,仅绑定 bootstrap,不接受 roles:
118+ 
119+| Rule ID | Collector | 判断 | 来源 |
120+|---|---|---|---|
121+| `CONFIG-INIT-CUSTOM-<KEY>` | `fileContent` 或受控 `exec` | `expression(actual)` 必须为 true | `RUNTIME-PREFLIGHT-CONFIG` |
122+ 
123+文件原文和脚本私有字段不得进入报告。完整配置、类型和安全边界见 SDK 提案。
124+ 
125+## 4. 依赖、错误与报告
126+ 
127+最小依赖:
128+ 
129+```text
130+离线文件存在 → 可读 → 格式
131+CA 文件存在 → 可读 → X.509 解析
132+```
133+ 
134+根依赖失败后下游为 SKIP,默认控制台只展示根因。输入缺失、类型错误、互斥参数和外部 policy
135+错误通过 RunIssue 显示“前置检查未启动”,不伪装成环境 FAIL。
136+ 
137+目标列必须包含 bootstrap 和具体对象,例如:
138+ 
139+- `bootstrap (192.0.2.10) / TCP 36443`
140+- `bootstrap / /bke`
141+- `bootstrap / Image repository example.com:443`
142+- `bootstrap / /etc/openFuyao/ca.crt`
143+ 
144+## 5. 只读、安全与质量属性
145+ 
146+- 不创建 Workspace、测试文件或目录,不下载、解压、安装或清理制品。
147+- 不修改服务、端口、网络、sysctl 或系统配置。
148+- 凭据只存在于 Host 短生命周期执行器中,不进入计划和报告。
149+- 总超时覆盖解析、计划、Bundle、采集、计算和渲染前阶段;单 Fact 受独立超时约束。
150+- 同一 `(bootstrap,factKey)` 只采集一次,不同独立事实可有界并发。
151+- 输入顺序变化不应改变 PlanHash;业务端口、来源或条件变化应改变 PlanHash。
152+ 
153+## 6. 测试与验收
154+ 
155+必须覆盖:
156+ 
157+- preflight 与真实 init 使用等价参数时解析结果一致,且没有安装副作用。
158+- 非法参数、缺文件、未知字段和 policy 错误可定位到字段或文件。
159+- Console、本地 NTP、离线、仓库和 CA 的适用/不适用分支。
160+- CPU、内存、磁盘、平台、TCP/UDP 端口和来源的边界值。
161+- 文件与 CA 根依赖失败时下游 SKIP。
162+- custom fileContent/exec 的成功、失败、类型、权限、超限和脱敏。
163+- text/JSON/output-file 的结论和计数一致,JSON stdout 为单一文档。
164+- Linux AMD64/ARM64 环境中的真实 CLI、端口占用、离线制品、仓库/CA 和只读审计。
165+ 
166+## 7. 参考资料
167+ 
168+- [openFuyao 统一前置检查提案](./openFuyao统一前置检查提案.md)
169+- [校验框架 SDK 提案](./校验框架SDK提案.md)
170+- [preflight-bundle-gen 提案](./preflight-bundle-gen提案.md)
@@ -0,0 +1,519 @@
1+# openFuyao 统一前置检查提案
2+ 
3+## 1. 特性描述
4+ 
5+### 1.1 背景
6+ 
7+`bke init``bke cluster create` 在真正安装前依赖业务输入、管理集群、本机和目标节点的多类
8+条件。现有错误通常在安装过程中才暴露,且网络、认证、权限、资源和配置问题容易被混在一起,
9+增加定位和恢复成本。
10+ 
11+本特性在 bke CLI 中提供独立、只读、可追溯的统一前置检查:
12+ 
13+```bash
14+bke preflight init [与 bke init 对等的业务参数]
15+ 
16+bke --kubeconfig /path/to/management.kubeconfig \
17+ preflight cluster-create \
18+ --file ./cluster.yaml \
19+ --nodes ./nodes.yaml
20+```
21+ 
22+前置检查负责生成最终检查计划、采集事实、使用发布规则计算结果并输出可修复报告;它不自动执行
23+安装命令,不安装、修复、清理或修改 Kubernetes 资源。用户处理 FAIL 和 WARN 后,再显式执行真正
24+的业务命令。
25+ 
26+### 1.2 目标
27+ 
28+- preflight 与业务命令复用输入解析、默认化和本地校验逻辑。
29+- 固定规则来自版本化 PreflightBundle,每条规则有真实、不可变的来源证据。
30+- Collector 只读采集,CEL 统一完成类型化计算和比较。
31+- 使用依赖图抑制单根因多 FAIL,并保留详细 SKIP 审计链路。
32+- 文本和 JSON 都能说明目标、期望、实际、原因和修复建议。
33+- 输入、Bundle、内部错误与真实环境不满足分别表达。
34+- 支持少量、受控、可审计的现场自定义检查。
35+ 
36+### 1.3 非目标
37+ 
38+- 不覆盖 build、Web、installer-service、website、升级和扩缩容。
39+- 不提前执行安装流程,不做 Kubernetes 写入或 server-side dry-run。
40+- 不自动修复、清理、启停服务、修改 sysctl 或创建测试文件。
41+- 不把历史 envCheck、node-checker 等工具的规则并集作为长期来源。
42+- 不增加无明确当前来源的残留路径、时钟、默认路由、iptables、SELinux、Swap、runtime socket、
43+ 50 GiB 等泛化检查。
44+- 不提供 `--request`、Bundle 覆盖或 Provider defaults 文件覆盖参数。
45+- 不提供通用表达式 DSL、CEL I/O 函数、内联 shell、脚本上传下载和隐式 sudo。
46+ 
47+### 1.4 使用者与职责
48+ 
49+| 角色 | 职责 |
50+|---|---|
51+| 安装操作员 | 使用与业务命令相同的输入运行检查,修复 FAIL、确认 WARN、保存报告 |
52+| BKE 开发者 | 维护共享 Resolver/Validate、Host Adapter、Collector 路由和 CLI |
53+| Provider 开发者 | 提供可复用的纯默认化与校验事实,不让 preflight 调用写路径 |
54+| 发布工程师 | 审核 policy/release-input,生成和 verify Bundle,不手工改生成产物 |
55+| 文档维护者 | 同步阶段规则、命令、配置、报告、限制和修复说明 |
56+ 
57+### 1.5 依赖与 License
58+ 
59+本特性依赖 bkeadm、cluster-api-provider-bke、Kubernetes 只读 API、CEL-Go、go-pretty 和 SSH
60+客户端能力。代码随 bkeadm 使用木兰宽松许可证第2版;第三方依赖必须经过仓库 License、漏洞和
61+供应链审查。
62+ 
63+## 2. 需求与场景
64+ 
65+### 2.1 用户流程
66+ 
67+init:
68+ 
69+```bash
70+bke preflight init \
71+ --hostIP 192.0.2.10 \
72+ --onlineImage cr.openfuyao.cn/openfuyao/bke-online-installed:latest \
73+ --installConsole=false
74+ 
75+# 用户处理报告后显式执行
76+bke init \
77+ --hostIP 192.0.2.10 \
78+ --onlineImage cr.openfuyao.cn/openfuyao/bke-online-installed:latest \
79+ --installConsole=false
80+```
81+ 
82+cluster-create:
83+ 
84+```bash
85+bke --kubeconfig /path/to/management.kubeconfig \
86+ preflight cluster-create -f cluster.yaml -n nodes.yaml
87+ 
88+# 用户处理报告后显式执行
89+bke --kubeconfig /path/to/management.kubeconfig \
90+ cluster create --file cluster.yaml --nodes nodes.yaml
91+```
92+ 
93+前置检查不缓存“已检查”状态。两次命令之间输入和环境可能变化,PASS 只表示报告中适用条件在检查
94+时满足,不保证后续安装必然成功。
95+ 
96+### 2.2 需求分解
97+ 
98+| 编号 | 需求 |
99+|---|---|
100+| R01 | 提供独立的 `preflight init``preflight cluster-create` 命令 |
101+| R02 | 与对应业务命令共享输入解析、默认化和校验语义 |
102+| R03 | 使用产品无关的 OperationPlan、RuleBinding、Fact 和 Report SDK |
103+| R04 | 使用固定发布 Bundle、SourceLock 和摘要保证规则可追溯 |
104+| R05 | Collector 与 CEL 分离,采集只读,计算唯一 |
105+| R06 | 支持依赖去噪、超时、取消和有界并发 |
106+| R07 | 支持完整外部 preflight.yaml 和受限 customChecks |
107+| R08 | 输出可读文本、详细报告和单一 JSON 文档 |
108+| R09 | 所有可见问题可定位、可解释并提供修复动作 |
109+| R10 | 建立生成、静态校验、单元测试和真实环境发布门禁 |
110+ 
111+### 2.3 威胁建模
112+ 
113+| 风险 | 影响 | 控制 |
114+|---|---|---|
115+| 安装凭据或自定义敏感值进入报告 | 密码、Token、私钥泄露 | Host 凭据只存于 executor/client;custom 使用 Display/publicFields 投影,scalar/list 由提供者按公开值审核 |
116+| 自定义脚本执行任意命令 | 环境被修改 | 禁止 raw shell/inline/`bash -c`/upload/sudo/env;只允许预装、安全权限的绝对路径脚本 |
117+| 恶意配置或输出 | 内存、CPU 或日志耗尽 | 严格 schema、大小限制、CEL 长度/成本、Fact 数量与类型契约 |
118+| TCP 结果被过度解释 | 产生错误修复建议 | transport、auth、privilege 分层;TCP 不解释为 HTTP/TLS/auth |
119+| 根依赖失败继续探测 | 告警风暴和额外风险 | 显式 DAG,下游 SKIP,不回退错误 Collector |
120+| 规则或来源漂移 | 不同二进制得出不可审计结果 | 内嵌 policy/Bundle、PolicyDigest、BundleDigest、SourceLock 和 verify |
121+ 
122+## 3. 总体设计
123+ 
124+### 3.1 架构
125+ 
126+```text
127+CLI flags / cluster.yaml / nodes.yaml / kubeconfig
128+
129+
130+ BKE Host Adapter
131+ - 共享 Resolver / Validate
132+ - 只读 Provider defaults / management facts
133+ - 生成 OperationPlan / RuleBinding / RunIssue
134+
135+
136+ 通用 preflight SDK ◀── 内嵌 policy + PreflightBundle
137+ - Plan/Bundle 契约校验 - 固定 Rule catalog
138+ - DAG / Collector - SourceLock
139+ - CEL evaluator - policy/bundle digest
140+
141+
142+ Report → 终端表格 / 详细文本 / JSON
143+```
144+ 
145+### 3.2 组件职责
146+ 
147+| 组件 | 输入 | 输出 | 责任边界 |
148+|---|---|---|---|
149+| CLI | flags、kubeconfig、运行参数 | 已解析请求和总体 context | 不执行安装;预期输入错误进入 Report |
150+| Host Resolver | init flags 或 cluster/nodes | 已默认化 AdapterInput | 复用业务纯逻辑;单次解析;无持久副作用 |
151+| Management/Provider | kubeconfig、ConfigMap 和 Provider | defaults、facts、ResolvedCluster | 同一 context;只读;错误准确归因 |
152+| Host Adapter | AdapterInput、policy | Plan、Bindings、Facts、Issues | 稳定 PlanHash;无敏感信息;不适用项不实例化 |
153+| Bundle loader | policy、Bundle、release | 已验证规则目录 | 校验摘要、DAG、SourceLock、类型和配对 |
154+| Collector Router | Subject、fact key | 一个 Fact | 只读;identity、type/value、Evidence 严格 |
155+| Engine | Rule、Binding、Fact | Result、Overall | 依赖后采集;类型错误不降级为环境 FAIL |
156+| Renderer | Report | text、JSON | 不重新计算状态、阈值、计数和退出码 |
157+ 
158+### 3.3 执行流程
159+ 
160+```text
161+建立总体 context
162+ → 加载并验证内嵌 policy/Bundle
163+ → 可选严格加载外部 preflight.yaml
164+ → 解析和校验业务输入
165+ → 读取 Provider defaults / management facts
166+ → 生成并校验 PlanHash、Bindings 和 RunIssues
167+ → 加载规则并构建实例 DAG
168+ → 按依赖和 (subject,key) 去重采集
169+ → 校验 Fact identity/type/value
170+ → CEL 计算四态 Result
171+ → 汇总 Report、渲染和返回退出码
172+```
173+ 
174+输入、策略、Bundle 或计划问题产生 `BLOCK_START` 时不启动 Collector。独立环境分支可继续执行;
175+Collector 或 Adapter 契约错误升级为 INTERNAL_ERROR。
176+ 
177+### 3.4 信任边界
178+ 
179+- 用户输入决定检查对象;外部 policy 只能调整 schema 允许的策略值和增加受控 customChecks。
180+- 内嵌 Bundle 固定规则身份、Fact 形状、operator、依赖、SourceLock、发布事实和 Collector 能力。
181+- Collector 只陈述事实,不直接产生 PASS/FAIL/WARN。
182+- CEL 只计算 typed Fact,不执行 I/O。
183+- Renderer 只展示 Report,不猜测规则业务语义。
184+ 
185+## 4. CLI、输入与运行控制
186+ 
187+### 4.1 公共参数
188+ 
189+| 参数 | 默认值 | 说明 |
190+|---|---|---|
191+| `--output` | `text` | `text``json` |
192+| `--output-file` | 空 | 保存 UTF-8 完整报告;默认文本运行可生成详细报告 |
193+| `--preflight-config` | 空 | 加载完整外部 preflight.yaml;空值使用内嵌策略 |
194+| `--timeout` | `10m` | 覆盖输入、management、Adapter、SDK 和渲染前阶段 |
195+| `--fact-timeout` | `30s` | 单个 `(subject,key)` 采集超时 |
196+| `--max-concurrency` | `0` | 0 为有界自适应;显式范围1..64 |
197+ 
198+自动化直接使用稳定 CLI 参数,不额外提供 `PreflightRequest`。cluster/nodes 必须是普通文件并严格
199+解析;机器调用应读取 JSON 的 overall、issues 和 results,而不是解析彩色文本。
200+ 
201+### 4.2 输入优先级
202+ 
203+```text
204+显式 init CLI / cluster.yaml / nodes.yaml / management Provider 值
205+ > 外部 policy fallback
206+ > 内嵌默认 policy
207+```
208+ 
209+policy 只改变本次检查计划,不修改业务命令输入。例如显式业务端口优先于 policy defaultPort;
210+资源 minimum 和平台矩阵等无业务参数的检查策略直接来自本次 policy。
211+ 
212+### 4.3 RunIssue 与退出码
213+ 
214+输入、计划和 setup 问题使用 RunIssue:
215+ 
216+```text
217+severity: INFO | WARN | ERROR
218+stage: INPUT | PLAN | SETUP | EXECUTION
219+effect: BLOCK_START | CONTINUE | INTERRUPT
220+code / field / cause / action / sourceRefs
221+```
222+ 
223+YAML 未知字段和类型错误应提供路径式 field;无法恢复路径的语法错误保留文件与行号。
224+ 
225+| Overall | 退出码 |
226+|---|---:|
227+| PASS | 0 |
228+| WARN 或全部 SKIP | 2 |
229+| FAIL | 3 |
230+| INPUT_ERROR / BUNDLE_ERROR | 4 |
231+| INTERNAL_ERROR | 5 |
232+| TIMED_OUT | 124 |
233+| CANCELED | 130 |
234+ 
235+## 5. 规则与配置设计
236+ 
237+### 5.1 固定规则范围
238+ 
239+| 阶段 | 固定模板 | 主要范围 |
240+|---|---:|---|
241+| init | 27 | 身份、平台、资源、工具、Workspace、端口、来源、离线制品、仓库和 CA |
242+| cluster-create | 46 | 输入、拓扑、管理集群、路径、CIDR、HA/addon、SSH、资源、平台、角色端口和来源 |
243+| customChecks | 每个 operation 0..64 | fileContent 或受控 exec 的 typed Fact |
244+ 
245+完整 Rule ID、条件和 Source ID 以两个阶段提案为准。
246+ 
247+规则进入固定目录必须同时满足:
248+ 
249+1. 有当前安装文档、BKE、Provider、manifest 或 release profile 的固定来源。
250+2. 能在业务动作前通过只读方式取得足够事实。
251+3. 失败时可给出明确且不误导的修复动作。
252+4. expected、operator、ValueType、level、unknown 和适用条件可静态表达。
253+5. SourceLock 完整且使用不可变 revision/digest。
254+6. 有正向、失败、未知、依赖、不适用和脱敏测试。
255+ 
256+“旧工具曾检查”“业界通常检查”或“可能有风险”不能单独成为规则来源。
257+ 
258+### 5.2 默认 preflight.yaml
259+ 
260+默认策略与匹配 Bundle 一起内嵌到 bke 单二进制。配置结构以 bkeadm
261+`configs/preflight/preflight.yaml` 为准:
262+ 
263+```yaml
264+apiVersion: preflight.openfuyao.io/v1
265+kind: PreflightConfig
266+metadata:
267+ release: v26.06
268+ description: Human-readable openFuyao init and cluster-create preflight policy
269+operations:
270+ init:
271+ platform:
272+ distributions:
273+ - name: openeuler
274+ version: "20.03"
275+ architectures: [amd64, arm64]
276+ kernelPrefixes: ["4.19."]
277+ - name: openeuler
278+ version: "22.03"
279+ architectures: [amd64, arm64]
280+ kernelPrefixes: ["5.10."]
281+ - name: openeuler
282+ version: "24.03"
283+ architectures: [amd64, arm64]
284+ kernelPrefixes: ["6.6."]
285+ - name: ubuntu
286+ version: "22.04"
287+ architectures: [amd64, arm64]
288+ kernelPrefixes: ["5.15."]
289+ - name: uos
290+ version: "20 1070e"
291+ architectures: [amd64, arm64]
292+ kernelPrefixes: ["4.19.", "5.10."]
293+ resources:
294+ - {key: cpu, description: Logical CPU count, minimum: 2}
295+ - {key: memory, description: Available memory, minimum: 4294967296}
296+ - {key: systemDisk, description: System disk capacity, minimum: 107374182400}
297+ tools:
298+ - {key: tar, description: tar executable, names: [tar]}
299+ - {key: systemctl, description: systemctl executable, names: [systemctl]}
300+ paths:
301+ - key: workspace
302+ description: Workspace is creatable and not read-only
303+ require: [create, notReadOnly]
304+ ports:
305+ - {key: kubernetes, description: Kubernetes API port, defaultPort: 36443, portFrom: port.kubernetes}
306+ - {key: imageRepo, description: Image repository port, defaultPort: 40443, portFrom: port.imageRepo}
307+ - {key: chart, description: Chart repository port, defaultPort: 38080, portFrom: port.chart}
308+ - {key: yum, description: Package repository port, defaultPort: 40080, portFrom: port.yum}
309+ - key: console
310+ description: BKE Console port
311+ defaultPort: 30010
312+ portFrom: port.console
313+ when: feature.installConsole
314+ - key: ntp
315+ description: Local NTP port
316+ defaultPort: 123
317+ protocol: udp
318+ when: feature.localNTP
319+ customChecks: []
320+ 
321+ clusterCreate:
322+ platform:
323+ distributions:
324+ - name: openeuler
325+ version: "20.03"
326+ architectures: [amd64, arm64]
327+ kernelPrefixes: ["4.19."]
328+ - name: openeuler
329+ version: "22.03"
330+ architectures: [amd64, arm64]
331+ kernelPrefixes: ["5.10."]
332+ - name: openeuler
333+ version: "24.03"
334+ architectures: [amd64, arm64]
335+ kernelPrefixes: ["6.6."]
336+ - name: ubuntu
337+ version: "22.04"
338+ architectures: [amd64, arm64]
339+ kernelPrefixes: ["5.15."]
340+ - name: uos
341+ version: "20 1070e"
342+ architectures: [amd64, arm64]
343+ kernelPrefixes: ["4.19.", "5.10."]
344+ topology:
345+ masters: {minimum: 1, odd: true}
346+ etcd: {minimum: 1}
347+ workers: {minimum: 1}
348+ unique: [hostname, ip]
349+ managementCluster:
350+ api: true
351+ discovery: true
352+ crds: [bkeclusters, bkenodes]
353+ requiredKubeconfig: kube-system/localkubeconfig
354+ resources:
355+ - {key: cpu, description: Node logical CPU count, minimum: 8}
356+ - {key: memory, description: Node available memory, minimum: 17179869184}
357+ - {key: systemDisk, description: Node system disk capacity, minimum: 107374182400}
358+ ports:
359+ - {key: apiServer, description: Node Kubernetes API port, defaultPort: 6443, portFrom: cluster.apiPort, roles: [master]}
360+ - {key: etcdClient, description: Etcd client port, defaultPort: 2379, roles: [etcd]}
361+ - {key: etcdPeer, description: Etcd peer port, defaultPort: 2380, roles: [etcd]}
362+ - {key: etcdMetrics, description: Etcd metrics port, defaultPort: 2381, roles: [etcd]}
363+ - {key: kubelet, description: Kubelet secure port, defaultPort: 10250, roles: [master, worker]}
364+ - {key: kubeletHealth, description: Kubelet health port, defaultPort: 10248, roles: [master, worker]}
365+ - {key: controllerManager, description: Controller manager port, defaultPort: 10257, roles: [master]}
366+ - {key: scheduler, description: Scheduler port, defaultPort: 10259, roles: [master]}
367+ - key: localHA
368+ description: Multi-master local HA port
369+ defaultPort: 36443
370+ roles: [master]
371+ when: cluster.topology.multiMaster
372+ - {key: bkeAgent, description: BKE Agent port, defaultPort: 58080, roles: [all]}
373+ customChecks: []
374+```
375+ 
376+### 5.3 外部策略
377+ 
378+`--preflight-config` 接受完整、严格解码的 preflight.yaml,不与内嵌 YAML 做字段级 merge。用户先
379+通过 `bke version` 获取 `gitCommitID`,再从 bkeadm 仓库同一修订的
380+`configs/preflight/preflight.yaml` 复制完整默认文件。外部策略:
381+ 
382+- 可以调整 schema 已声明的平台、资源阈值、端口 fallback、条件、角色、failure/unknown 和建议。
383+- 必须保留默认 policy 已有的固定配置键,不能通过删除列表关闭发布检查。
384+- 必须与当前 release 匹配,未知字段或无法投影的值使检查不启动。
385+- 不能覆盖固定 Rule ID、fact、operator、dependsOn、SourceRef、发布事实和 Provider defaults。
386+- 合法 customChecks 按固定公式生成 Rule ID,并进入本次内存 Bundle。
387+- 只改变本次检查,不改变后续安装行为。
388+ 
389+### 5.4 自定义检查
390+ 
391+自定义项直接放入对应 operation:
392+ 
393+```yaml
394+operations:
395+ init:
396+ customChecks:
397+ - key: hosts-loopback
398+ description: /etc/hosts 回环地址配置
399+ expected: 包含 127.0.0.1 或 ::1 回环地址映射
400+ collector:
401+ type: fileContent
402+ path: /etc/hosts
403+ expression: >-
404+ actual.matches('(?m)^\\s*(127\\.0\\.0\\.1|::1)(\\s|$)')
405+ failure: fail
406+ unknown: fail
407+ remediation: 补充回环地址映射后重试
408+```
409+ 
410+`fileContent` 最多读取64 KiB,原文只进入 CEL;报告仅记录路径、Collector 和观测摘要。
411+ 
412+`exec` 只执行节点上预装、安全权限的绝对路径脚本,使用结构化 args。resultType 支持 bool、
413+integer、string、stringList、integerList 和 object;object 必须通过 publicFields 声明报告可见字段。
414+脚本 stdout 必须是单一 typed Fact JSON,不能直接返回 PASS/FAIL。用户不填写 digest,由 Host 计算
415+观测 SHA-256。fileContent 原文和 object 非公开字段不进入报告;scalar/list value 会作为实际值展示,
416+必须只返回可公开内容。完整契约见 SDK 提案。
417+ 
418+## 6. 报告与可修复性
419+ 
420+### 6.1 Report
421+ 
422+Report 包含 schemaVersion、operation、planHash、configDigest、bundleDigest、overall、exitCode、
423+summary、issues 和 results。Result 至少包含规则/实例 ID、名称、状态、Subject、typed
424+Expected/Actual、Evidence、SourceRefs、原因、依赖和修复建议。
425+ 
426+公开检查状态只有 PASS、FAIL、WARN、SKIP。不适用项不产生 Result;Summary 满足
427+`total = pass + fail + warn + skip`
428+ 
429+### 6.2 文本和 JSON
430+ 
431+宽终端使用六列表格:
432+ 
433+| 状态 | 检查项 | 目标 | 期望 | 实际 | 原因及建议 |
434+|---|---|---|---|---|---|
435+ 
436+- 目标同时说明节点/管理集群/本机和具体字段、端口、路径或来源。
437+- 期望与实际分列,原因与建议合并且保持简洁。
438+- 按终端显示宽度动态分配列宽,中文、英文和 Unicode 正确对齐。
439+- 窄于72列时降级为纵向布局,不超过真实窗口宽度。
440+- 控制台只展开 RunIssue 和 FAIL/WARN;完整 text/JSON 保留四态。
441+- JSON stdout 为单一文档,进度只写 stderr。
442+ 
443+每个可见问题至少回答:目标是什么、检查什么、期望与实际是什么、根因属于哪一层、用户应修改
444+哪个 flag/YAML 字段/节点状态并如何重试。证据不足时不得编造更细的原因。
445+ 
446+## 7. 只读、安全与质量属性
447+ 
448+| 边界 | 允许 | 禁止 |
449+|---|---|---|
450+| 本机 | stat、挂载、端口、文件存在/可读/格式和 TCP | 创建目录/测试文件、改服务、安装和清理 |
451+| Kubernetes | Discovery、GET、LIST | CREATE、UPDATE、PATCH、DELETE、server-side dry-run |
452+| SSH | transport/auth/privilege、固定只读命令、direct-tcpip | raw shell/inline、上传、隐式 sudo、安装和清理 |
453+| 来源 | host:port TCP | HTTP HEAD、TLS、认证、对象下载 |
454+| 报告 | 脱敏 endpoint、主体、路径、摘要和公开字段 | 密码、Token、私钥、完整 kubeconfig/Secret |
455+ 
456+质量属性:
457+ 
458+- 可靠性:根因去噪、明确错误域、总体/单 Fact 超时和有界并发。
459+- 安全性:默认只读、最小权限、敏感信息结构性隔离、自定义脚本受控。
460+- 兼容性:schemaVersion 管理演进;未知字段严格拒绝;CLI 参数保持稳定。
461+- 可服务性:每条可见问题可定位和修复;详细报告可归档。
462+- 可测试性:Host、Bundle、Collector、CEL、DAG 和 Renderer 可独立注入和测试。
463+- 性能:Fact 按 `(subject,key)` 去重;并发有硬上限;输入和输出有大小限制。
464+ 
465+## 8. 用户文档
466+ 
467+本特性只提交中文用户文档:
468+ 
469+| 文档 | 内容 |
470+|---|---|
471+| `docs/zh/cluster_installation_guide/environment_preparation/before_you_start.md` | 安装前推荐运行对应 preflight,说明只读和 envCheck 边界 |
472+| `docs/zh/cluster_installation_guide/appendix/command_reference.md` | 命令、参数、配置、报告和退出码 |
473+| `docs/zh/cluster_installation_guide/environment_preparation/environment_pre_check_tool_guide.md` | 区分统一 preflight 与旧 envCheck 的能力和风险 |
474+ 
475+## 9. 测试与验收
476+ 
477+### 9.1 测试范围
478+ 
479+- 共享 Resolver/Validate、PlanHash、Binding 和适用条件。
480+- 73个固定模板与两个阶段清单、policy、Bundle 和 SourceLock 一致。
481+- Bundle generate/verify、摘要、SourceLock、DAG、类型和篡改检测。
482+- local、artifact、endpoint、Kubernetes、SSH、custom Collector 契约和只读性。
483+- CEL 内置 operator、custom expression、类型和成本边界。
484+- 输入/Bundle/内部错误、依赖 SKIP、超时、取消和退出码。
485+- 15/60/72/80/120/220列终端、中文显示、text/JSON/output-file 和单 JSON 文档。
486+- Linux AMD64/ARM64 的真实 CLI、SSH、Kubernetes 和只读审计;fake collector 不替代真实 E2E。
487+ 
488+### 9.2 验收标准
489+ 
490+1. preflight 与业务命令使用等价输入时,最终业务值和检查对象一致。
491+2. 固定规则数量、ID、条件、阈值、依赖和来源与 Bundle 一致。
492+3. 输入、Bundle、类型和框架错误不被渲染为普通环境 FAIL。
493+4. 根依赖失败后不继续无意义探测,不扩散多条可见 FAIL。
494+5. 每条 FAIL/WARN 可定位目标并给出证据支持的修复建议。
495+6. 文本在真实终端宽度下可读,JSON 可稳定解析和归档。
496+7. 默认执行过程只读,不产生安装、修复、清理和 Kubernetes 写副作用。
497+8. Bundle 可确定性重建、verify 和篡改检测,发布入口执行对应门禁。
498+ 
499+## 10. 需求分配与修改日志
500+ 
501+| 需求 | 主要承载模块 | 验收入口 |
502+|---|---|---|
503+| R01、R02 | BKE CLI / Host Adapter | 两阶段 CLI 与业务 Resolver/Validate 一致性测试 |
504+| R03、R05、R06 | SDK、Collector、CEL、DAG | SDK 单测、类型/依赖/超时测试和真实环境验证 |
505+| R04 | Bundle compiler、SourceLock、generator | generate/verify、摘要和篡改测试 |
506+| R07 | Runtime policy、custom Collector | 完整配置、兼容性、安全和 customChecks 测试 |
507+| R08、R09 | Report、Renderer、中文用户文档 | text/JSON golden、终端宽度和可修复性验收 |
508+| R10 | Makefile 与发布入口 | 单元测试、Bundle 门禁和 Linux E2E |
509+ 
510+| 版本 | 说明 |
511+|---|---|
512+| v1 | 统一 init 与 cluster-create 前置检查的首版提案 |
513+ 
514+## 11. 参考资料
515+ 
516+- [init 阶段检查项提案](./init阶段检查项提案.md)
517+- [cluster-create 阶段检查项提案](./cluster-create阶段检查项提案.md)
518+- [校验框架 SDK 提案](./校验框架SDK提案.md)
519+- [preflight-bundle-gen 提案](./preflight-bundle-gen提案.md)
@@ -0,0 +1,177 @@
1+# preflight-bundle-gen 提案
2+ 
3+## 1. 特性描述
4+ 
5+`preflight-bundle-gen` 将人维护的 `preflight.yaml`、固定规则目录和发布事实编译为确定性的
6+`PreflightBundle`。Bundle 是 `bke preflight` 的发布规则载体,用于固定本版本的规则、依赖、来源、
7+平台、端口和制品事实,并证明运行时加载的策略与发布审核结果一致。
8+ 
9+生成器只服务仓库开发和发布流程,不是用户运行前置检查的入口。用户通过
10+`--preflight-config` 加载外部策略时,运行时只能在内嵌规则目录允许的范围内投影配置,不能替换
11+SourceLock、发布事实或 Collector 契约。
12+ 
13+### 1.1 目标
14+ 
15+- 同一输入生成字节级一致的 Bundle。
16+- 每条固定规则可追溯到真实 repo、固定 revision、path、locator 和 sourceURL。
17+- 在发布前发现策略、代码、Provider、manifest 和制品事实冲突。
18+- 通过摘要和 exact-byte verify 发现策略或 Bundle 漂移。
19+- 生成过程不初始化日志、kubeconfig、Provider runtime 或网络客户端。
20+ 
21+### 1.2 非目标
22+ 
23+- 不从历史 envCheck、node-checker 等仓库自动汇总规则。
24+- 不根据运行环境动态生成发布规则。
25+- 不允许用户直接编辑生成后的 Bundle 作为正式输入。
26+- 不负责执行前置检查或安装命令。
27+ 
28+### 1.3 依赖与 License
29+ 
30+生成器复用 bkeadm 内部的 `preflightconfig``preflightbundlecompiler`、SDK Bundle 和
31+release facts 包,不引入独立服务。代码随 bkeadm 使用木兰宽松许可证第2版发布;新增第三方依赖
32+必须通过仓库现有 License 与供应链审查。
33+ 
34+## 2. 输入与输出
35+ 
36+### 2.1 输入
37+ 
38+| 输入 | 作用 |
39+|---|---|
40+| `configs/preflight/preflight.yaml` | 人维护的平台、资源、端口、条件、级别、建议和自定义检查默认值 |
41+| static catalog | 固定 Rule ID、operation、fact、operator、dependsOn 和 Source ID |
42+| `release-profile.yaml` | release、channel、规则目录和组件 revision |
43+| `source-lock.yaml` | Source ID 到真实源码位置的映射 |
44+| `docs-facts.yaml` | 安装文档中的资源、平台和操作要求 |
45+| `bke-facts.yaml` | bke 参数、端口、路径和来源事实 |
46+| `provider-facts.yaml` | Provider 校验、拓扑、管理依赖和默认值事实 |
47+| `manifest-requirements.yaml` | 角色端口和 manifest 约束 |
48+| `artifact-index.yaml` | 制品名称、摘要、架构、格式、签名和信任状态 |
49+ 
50+历史工具只可作为发现候选的线索;规则进入发布目录前仍需当前安装契约和固定来源证明。
51+ 
52+### 2.2 输出
53+ 
54+```yaml
55+schemaVersion: v1
56+release: v26.06
57+policyDigest: sha256:...
58+bundleDigest: sha256:...
59+operations: [init, cluster-create]
60+staticRuleCatalog: policy-catalog-v1
61+rules: []
62+releaseFacts: {}
63+artifacts: []
64+verifiedPlatforms: []
65+sourceLock: []
66+```
67+ 
68+默认发布目录包含 init 27 个、cluster-create 46 个固定 RuleTemplate。运行时实例数由
69+OperationPlan、节点、角色、端口、来源和适用条件决定。
70+ 
71+## 3. 命令与生成流程
72+ 
73+```bash
74+go run ./tools/preflight-bundle-gen generate \
75+ --preflight-config configs/preflight/preflight.yaml \
76+ --release-input release-input \
77+ --output assets/preflight/preflight-bundle.yaml
78+ 
79+go run ./tools/preflight-bundle-gen verify \
80+ --preflight-config configs/preflight/preflight.yaml \
81+ --release-input release-input \
82+ --bundle assets/preflight/preflight-bundle.yaml
83+```
84+ 
85+生成流程:
86+ 
87+```text
88+严格加载 policy 和 release-input
89+ → 校验 release、channel 和组件 revision
90+ → 合并固定规则与发布事实并检查冲突
91+ → 绑定 SourceLock、平台、manifest 和制品
92+ → 计算 PolicyDigest
93+ → 校验 Bundle 静态契约
94+ → 计算 BundleDigest
95+ → 输出确定性 YAML
96+```
97+ 
98+`generate` 使用原子替换并生成 `0644` 文件。`verify` 重新编译并进行 exact-byte 比较;输入、顺序、
99+摘要或内容发生漂移均应失败。
100+ 
101+## 4. 静态门禁
102+ 
103+### 4.1 规则与依赖
104+ 
105+- schema、release、operation 和 Rule ID 必须合法且唯一。
106+- operator、expected、ValueType、level、unknown、source 和 remediation 必须完整。
107+- DependsOn 不得悬空、重复、跨 operation、自依赖或形成环。
108+- CEL 必须在生成阶段完成编译和返回类型校验。
109+- policy、Provider、manifest 与 release facts 中的同一端口或阈值必须一致,冲突即失败。
110+ 
111+### 4.2 SourceLock
112+ 
113+每条固定规则的 Source ID 必须解析到完整记录:
114+ 
115+```yaml
116+sourceID: CAPBKE-VALIDATION
117+authority: current-code
118+repositoryURL: https://gitcode.com/openFuyao/cluster-api-provider-bke
119+revisionOrDigest: <immutable-revision>
120+path: common/cluster/validation/validation.go
121+locator: BKECluster and BKENode validation
122+sourceURL: https://gitcode.com/openFuyao/cluster-api-provider-bke/blob/<revision>/common/cluster/validation/validation.go
123+sourceStatus: official
124+```
125+ 
126+空仓库、浮动或占位 revision、空 path/locator/sourceURL、未知来源和规则悬空来源均不得发布。
127+ 
128+### 4.3 平台、制品与敏感信息
129+ 
130+- 平台记录必须包含发行版、版本、架构和内核前缀;正式通道还需测试与审批引用。
131+- 制品必须包含 basename、digest、架构和格式,不得包含本机绝对路径。
132+- 正式通道必须满足签名和信任材料要求。
133+- policy、release-input 和 Bundle 禁止密码、Token、私钥、完整 kubeconfig、凭据 URL 和节点地址。
134+ 
135+## 5. 摘要与运行时配对
136+ 
137+- `PolicyDigest` 标识严格解码并规范化后的策略内容。
138+- `BundleDigest` 标识摘要字段置空后的规范化 Bundle 内容。
139+- 默认运行时必须验证内嵌 policy 与 Bundle 的 release、PolicyDigest 和 BundleDigest。
140+- 外部 `--preflight-config` 必须与当前 release 匹配,并保留默认固定配置键;运行时重新计算本次
141+ ConfigDigest/BundleDigest,但不能替换内嵌 SourceLock、发布事实、规则身份和 Collector。
142+- 配对失败产生结构化 `BUNDLE_ERROR``INPUT_ERROR`,不得回退到另一份策略继续执行。
143+ 
144+## 6. 发布集成
145+ 
146+Makefile 应提供并维护:
147+ 
148+```bash
149+make generate-preflight-bundle
150+make verify-preflight-bundle
151+make test-preflight
152+make release
153+make docker-build
154+```
155+ 
156+正式发布入口必须在构建前执行 verify,任一架构失败应使整体失败。单二进制内嵌默认
157+`preflight.yaml` 与匹配 Bundle,默认运行不依赖旁置文件。
158+ 
159+## 7. 质量属性与测试
160+ 
161+| 属性 | 要求 |
162+|---|---|
163+| 确定性 | 相同输入生成相同字节、相同摘要和稳定排序 |
164+| 安全性 | 严格输入、无敏感信息、无网络和运行时初始化副作用 |
165+| 可靠性 | 原子写入;参数、输入或校验失败时不留下半成品 |
166+| 兼容性 | schemaVersion 控制演进;未知字段严格拒绝 |
167+| 可测试性 | compiler、CLI、摘要、SourceLock、DAG 和篡改场景可独立测试 |
168+ 
169+必须覆盖正常 generate/verify、重复执行、输出权限、参数缺失、未知参数、摘要篡改、SourceLock
170+缺失、端口冲突、DAG 环、类型错误、CEL 错误、制品错误、运行时内嵌配对和外部策略配对。
171+ 
172+## 8. 参考资料
173+ 
174+- [openFuyao 统一前置检查提案](./openFuyao统一前置检查提案.md)
175+- [校验框架 SDK 提案](./校验框架SDK提案.md)
176+- [init 阶段检查项提案](./init阶段检查项提案.md)
177+- [cluster-create 阶段检查项提案](./cluster-create阶段检查项提案.md)
@@ -0,0 +1,420 @@
1+# 校验框架 SDK 提案
2+ 
3+## 1. 特性描述
4+ 
5+前置检查 SDK 提供与产品命令解耦的计划校验、事实采集编排、CEL 规则计算和报告契约。BKE 的
6+CLI、Provider、节点角色、默认值和业务输入由 Host Adapter 负责,SDK 只理解通用 OperationPlan、
7+RuleBinding、Bundle、Fact、依赖和 Report。
8+ 
9+```text
10+BKE CLI / 配置
11+ → BKE Host Adapter
12+ → ResolveResult(Plan、Bindings、Facts、Issues)
13+ → 通用 SDK + PreflightBundle + Collector
14+ → Report
15+```
16+ 
17+SDK 是 bkeadm 中的独立 Go module `gopkg.openfuyao.cn/preflight`。它不依赖 Cobra,不读取产品
18+配置或环境变量,不调用 `os.Exit`,不直接写 stdout/stderr,也不硬编码 init/cluster-create 的解析。
19+ 
20+### 1.1 目标
21+ 
22+- 统一表达业务输入、事实、规则、依赖、问题和结果。
23+- 同一 Plan、Bundle 和 Facts 得到确定性相同的 Report。
24+- 将输入错误、事实不可得、规则不满足和框架违约分为不同错误域。
25+- 所有环境访问通过显式 Collector 注入,SDK core 无隐式 I/O。
26+- 通过 DAG 抑制单根因多 FAIL,并保留可审计的 SKIP 链路。
27+- Expected、Actual、Evidence 和 Remediation 足以直接生成可修复报告。
28+- 固定 operator 和 custom rule 使用同一 CEL 计算内核。
29+ 
30+### 1.2 非目标
31+ 
32+- SDK 不承诺后续安装成功,也不替代 Provider 最终校验。
33+- 不在 SDK 中解析 BKE CLI、cluster/nodes 或 Kubernetes CRD。
34+- 不提供通用表达式 DSL、CEL I/O 函数或任意 shell 执行能力。
35+- 不允许 renderer、Collector 或 Host 各自维护第二套状态计算。
36+ 
37+### 1.3 依赖与 License
38+ 
39+SDK 核心直接依赖 Go context、CEL-Go、go-pretty、`x/term` 和 YAML 库。Kubernetes client-go 与
40+`x/crypto/ssh` 属于 bkeadm Host 层,通过 Collector/executor 接口注入。SDK 与 bkeadm 使用木兰
41+宽松许可证第2版;新增第三方依赖必须经过仓库 License、漏洞和供应链审查。
42+ 
43+## 2. 架构与包职责
44+ 
45+| 包 | 职责 |
46+|---|---|
47+| `api` | Plan、Binding、Fact、RunIssue、Result、Report、Bundle 等 DTO |
48+| `normalize` | Plan 规范化与 PlanHash |
49+| `bundle` | Bundle 解析、摘要和静态契约校验 |
50+| `celcheck` | CEL 环境、表达式长度、成本、编译和求值 |
51+| `engine` | DAG、Fact 去重采集、类型校验、求值和 Overall |
52+| `collectors` | local、artifact、endpoint、Kubernetes、SSH、custom 等事实能力 |
53+| `render` | 动态终端文本、详细文本和 JSON 渲染 |
54+| Host Adapter | 位于 bkeadm 根模块,处理产品输入、Provider、凭据和 Collector 组装 |
55+ 
56+依赖方向必须保持:CLI/Host 可以依赖 SDK;SDK 不得反向依赖 Cobra、bkeadm 产品包、Provider
57+runtime 或具体 Kubernetes client 实现。
58+ 
59+## 3. Host API
60+ 
61+### 3.1 主入口
62+ 
63+```go
64+type CheckInput struct {
65+ Resolved api.ResolveResult
66+ Release api.ReleaseRef
67+ Bundle []byte
68+ ConfigDigest api.Digest
69+ Runtime api.RuntimeOptions
70+ Progress api.ProgressFunc
71+}
72+ 
73+type Dependencies struct {
74+ Collector api.Collector
75+ ExpectedRelease string
76+ ExpectedBundleDigest api.Digest
77+ BundleValidator func(*api.PreflightBundle) error
78+}
79+ 
80+Check(ctx context.Context, in CheckInput) (api.Report, error)
81+```
82+ 
83+`CheckInput` 不携带 Credentials、Internal、AppliesWhen 等死字段。凭据只存在于 Host 注入的短生命
84+周期 executor/client 中。
85+ 
86+预期的输入和 Bundle 问题写入 Report,分别形成 `INPUT_ERROR``BUNDLE_ERROR`;非 nil Go error
87+仅用于 SDK 或 Collector 契约故障,并由最外层转为结构化 `INTERNAL_ERROR`
88+ 
89+### 3.2 Host 调用顺序
90+ 
91+```text
92+总体 context
93+ → 严格解析和业务 Validate
94+ → Adapter ResolveResult
95+ → SDK 校验 Plan/Bindings
96+ → Bundle 解析、摘要和静态校验
97+ → 过滤不适用项并构建实例 DAG
98+ → Collector 采集和 CEL 计算
99+ → Report
100+ → Host renderer / exit code
101+```
102+ 
103+Host 不得在 Check 后用第二套业务条件重算结果,也不得在 management/SSH setup 失败时切换到不
104+支持该事实的本地 Collector。
105+ 
106+### 3.3 ResolveResult
107+ 
108+```go
109+type ResolveResult struct {
110+ Plan OperationPlan
111+ Issues []RunIssue
112+ Bindings []RuleBinding
113+ Facts []Fact
114+}
115+```
116+ 
117+Adapter 已能只读取得的计划级事实可通过 Facts 传入;动态本机、节点和管理集群事实仍由 Collector
118+按请求采集。
119+ 
120+## 4. OperationPlan 与 RuleBinding
121+ 
122+### 4.1 OperationPlan
123+ 
124+```go
125+type OperationPlan struct {
126+ SchemaVersion string
127+ Operation Operation
128+ Subjects []Subject
129+ Values map[string]Value
130+ Sources []Source
131+ Origin PlanOrigin
132+ PlanHash Digest
133+}
134+```
135+ 
136+- Subject 是本机、cluster 范围或节点等稳定目标,包含 ID、role、address 和非敏感 metadata;
137+ 管理集群事实可绑定到 cluster 范围并用 Evidence locator 定位对象。
138+- Value 是 Adapter 解析后的 typed 最终业务值,不包含 comparator、level 或表达式。
139+- Source 描述本次操作真实使用的 endpoint、kind、objectPath 和非敏感 AuthRef。
140+- PlanHash 覆盖 operation、Subject、role、address、metadata、Values 和 Sources 的规范化内容。
141+- RuleBinding 必须完全复用 Plan 中的 canonical Subject,不能用相同 ID 替换地址或 SSH 端口。
142+- 密码、Token、私钥、完整 kubeconfig 和带凭据 URL 禁止进入 Plan 和摘要。
143+ 
144+Subjects、roles、metadata、Values 和 Sources 均需稳定排序。只改变输入列表或 map 遍历顺序不应
145+改变 PlanHash;节点、角色、端口、来源或功能条件变化应改变 PlanHash。
146+ 
147+### 4.2 RuleBinding
148+ 
149+```go
150+type RuleBinding struct {
151+ TemplateID string
152+ InstanceID string
153+ Name string
154+ Fix string
155+ Subject Subject
156+ Fact string
157+ Applicable bool
158+}
159+```
160+ 
161+Binding 只负责将可信模板绑定到具体 Subject 和 fact key,不能覆盖 expected、level、unknown、
162+operator、dependsOn 或 SourceRef。`Applicable=false` 在建图前过滤,不产生 Result 或 SKIP,也不能
163+因为无效模板触发 Bundle 错误。
164+ 
165+## 5. Bundle 与规则契约
166+ 
167+```go
168+type RuleTemplate struct {
169+ ID string
170+ Name string
171+ Operation Operation
172+ Fact string
173+ Op Op
174+ Expected any
175+ Level FailureSeverity
176+ Unknown UnknownPolicy
177+ Source string
178+ Fix string
179+ DependsOn []string
180+ Expression string
181+}
182+```
183+ 
184+### 5.1 状态策略
185+ 
186+| 字段 | 值 | 结果语义 |
187+|---|---|---|
188+| level | `ERROR` | 不满足期望时 FAIL |
189+| level | `WARNING` | 不满足期望时 WARN |
190+| level | `INFO` | 满足时 PASS,不满足时观察型 SKIP |
191+| unknown | `BLOCK` | 事实不可取得时 FAIL |
192+| unknown | `WARN` | 事实不可取得时 WARN |
193+| unknown | `IGNORE` | 事实不可取得时 SKIP |
194+ 
195+只有 `Fact.Available=false` 才进入 unknown 策略。已取得但不满足的事实、规则类型错误和 Collector
196+契约错误不能伪装成 UNKNOWN。
197+ 
198+### 5.2 CEL 计算
199+ 
200+公开 operator 为 `eq``in``gte``lte``range``exists``free``reachable`
201+`relation``cel`。前九种由 SDK 映射为固定 CEL 表达式;只有 custom rule 携带受限 expression。
202+ 
203+CEL 仅暴露 `actual: dyn`,不注册文件、网络、时间、命令或产品函数。表达式最长2048字节,执行
204+成本上限10000,结果必须为 bool。配置编译错误属于 INPUT_ERROR,Bundle 编译错误属于
205+BUNDLE_ERROR,运行期类型或求值错误属于 INTERNAL_ERROR。
206+ 
207+### 5.3 Bundle 静态校验
208+ 
209+加载时必须依次校验:
210+ 
211+1. 严格单文档 YAML、大小、schemaVersion、release 和 operation。
212+2. PolicyDigest、BundleDigest 和预期 release 配对。
213+3. Rule 必填字段、唯一 ID、operator/expected、level、unknown 和 ValueType。
214+4. DependsOn 悬空、重复、跨 operation、自依赖和环。
215+5. 每个 Source ID 可解析到完整 SourceLock。
216+6. artifacts、verifiedPlatforms、签名和审批约束。
217+7. Host 注入的 policy/release facts 与产品目录一致性。
218+ 
219+失败形成单一可定位 setup issue,不启动 Collector。
220+ 
221+## 6. Fact 与 Collector 契约
222+ 
223+```go
224+type Fact struct {
225+ Key string
226+ Subject string
227+ Value any
228+ Type ValueType
229+ Available bool
230+ Evidence []Evidence
231+ Error *FactError
232+ Display *DisplayValue
233+}
234+```
235+ 
236+### 6.1 请求与返回
237+ 
238+- 一个请求恰好包含一个 `(subject,key)`
239+- Collector 成功时恰好返回一个相同 identity 的 Fact。
240+- 零个、多个、错误 key、错误 subject、非法 availability/error 组合均为 INTERNAL_ERROR。
241+- `Available=false` 必须携带受支持的 NOT_FOUND、PERMISSION_DENIED、UNREACHABLE、TIMEOUT、
242+ UNSUPPORTED 或 PARSE_ERROR。
243+- Collector 只返回事实和安全 Evidence,不决定 PASS、FAIL 或 WARN。
244+ 
245+### 6.2 类型与展示
246+ 
247+SDK ValueType 包括 bool、integer、bytes、duration、string、enum、address、set、range、relation 和
248+object。Fact.Type 为空时才允许推断;非空时必须合法且 Value 与声明类型一致。规则 expected 类型
249+错误属于 BUNDLE_ERROR,Collector 类型错误属于 INTERNAL_ERROR。
250+ 
251+Result.Expected 和 Result.Actual 必须传播 DisplayValue.Type。Fact.Display 是安全投影;evaluator
252+读取完整 Value,Result 优先展示 Display,防止文件原文和 object 私有字段泄露。
253+ 
254+### 6.3 Collector 能力
255+ 
256+| Collector | 能力 | 边界 |
257+|---|---|---|
258+| Local | identity、平台、资源、工具、路径、挂载、端口、文件、TCP | 不创建路径或测试文件,不改系统 |
259+| Artifact | 离线制品存在、可读、格式和受信属性 | 不解压、安装或执行制品 |
260+| Kubernetes | API、Discovery、CRD、Secret、Provider defaults | 只允许 GET/LIST/Discovery |
261+| SSH | 独立 transport/auth/privilege、固定只读命令、端口、direct-tcpip | 不上传、不安装;当前不验证 host key |
262+| Endpoint | host:port TCP dial | 不做 HTTP、TLS、认证或对象查询 |
263+| Custom | fileContent、预装绝对路径 exec | 不接受 raw shell/inline/`bash -c`/upload/sudo/env;64 KiB 和安全投影 |
264+ 
265+Router 的匹配顺序是安全契约:远端节点必须先匹配 SSH route,setup 失败不得落入本地 route。
266+ 
267+## 7. DAG、并发与 Context
268+ 
269+- 引擎先构建模板 DAG,再按 Subject 绑定为实例 DAG。
270+- 默认优先查找同 Subject 依赖,必要时回退到计划级依赖。
271+- 根依赖 FAIL/WARN 后,下游适用项为 SKIP 并引用最早根因。
272+- 不同独立分支可继续执行;同一 `(subject,key)` 只采集一次。
273+- `MaxConcurrency=0` 为有界自适应,显式范围1..64;并发不得改变结果排序。
274+- 总体 context 由 Host 创建,覆盖 management defaults、Adapter、SDK 和客户端。
275+- 每个 probe 从总体 context 派生 FactTimeout;不得使用 `context.Background()` 丢失取消链。
276+- timeout 和 cancel 分别产生 TIMED_OUT、CANCELED,进度不得显示100%完成。
277+ 
278+## 8. RunIssue、Report 与 Renderer
279+ 
280+```go
281+type RunIssue struct {
282+ Code string
283+ Severity INFO | WARN | ERROR
284+ Stage INPUT | PLAN | SETUP | EXECUTION
285+ Effect BLOCK_START | CONTINUE | INTERRUPT
286+ Field string
287+ Cause string
288+ Action string
289+ SourceRefs []string
290+}
291+```
292+ 
293+缺参数、严格 YAML、Provider defaults、Bundle 配对和框架错误使用 RunIssue;环境事实不满足使用
294+Result。`BLOCK_START` 统一展示“前置检查未启动”,用户可修复问题不能只返回裸 Go error。
295+ 
296+```go
297+type Report struct {
298+ SchemaVersion string
299+ Operation Operation
300+ PlanHash Digest
301+ ConfigDigest Digest
302+ BundleDigest Digest
303+ Overall Overall
304+ ExitCode int
305+ Summary Summary
306+ Issues []RunIssue
307+ Results []Result
308+}
309+```
310+ 
311+公开状态只有 PASS、FAIL、WARN、SKIP。Summary 必须满足
312+`total = pass + fail + warn + skip = len(results)`;不适用项不进入 total。FAIL/WARN 必须有原因或
313+修复建议,依赖 SKIP 必须引用根因。
314+ 
315+Renderer 只消费 Report,不访问 Collector、Bundle 或业务配置,也不重算阈值、状态、Overall 和
316+退出码。宽终端使用“状态、检查项、目标、期望、实际、原因及建议”六列;窄终端降级为纵向布局。
317+JSON 必须是单一文档。
318+ 
319+## 9. 自定义扩展
320+ 
321+customChecks 只覆盖常见现场差异,不追求任意能力:
322+ 
323+| 字段 | 约束 |
324+|---|---|
325+| key | operation 内唯一,生成固定 Rule ID 和 fact key |
326+| description/expected/remediation | 必填,分别用于名称、期望和修复建议 |
327+| failure/unknown | fail、warn、skip,映射到 SDK 级别和 unknown 策略 |
328+| roles/when | init 禁止 roles;cluster 仅允许 master/worker/etcd/all,all 不混用;when 是 Plan bool key,false 不实例化 |
329+| fileContent | clean absolute path,最多64 KiB,原文不进入报告 |
330+| exec | 预装绝对路径、结构化 args、普通可执行且非 group/world writable |
331+| resultType | bool、integer、string、stringList、integerList、object |
332+| publicFields | object 必填,只有声明字段进入报告 |
333+| expression | 只读取 actual,长度和成本受限,结果必须 bool |
334+ 
335+最小配置示例:
336+ 
337+```yaml
338+customChecks:
339+ - key: runtime-health
340+ description: 容器运行时状态
341+ expected: 运行时健康
342+ collector:
343+ type: exec
344+ path: /usr/local/libexec/check-runtime
345+ args: [--format, fact]
346+ resultType: object
347+ publicFields: [runtime, healthy]
348+ expression: actual.healthy == true
349+ failure: fail
350+ unknown: fail
351+ remediation: 检查容器运行时服务后重试
352+```
353+ 
354+脚本 stdout 必须只包含一个 `preflight.openfuyao.io/fact/v1` JSON。可用事实示例:
355+ 
356+```json
357+{
358+ "apiVersion": "preflight.openfuyao.io/fact/v1",
359+ "available": true,
360+ "type": "object",
361+ "value": {"runtime": "containerd", "healthy": true, "privateDetail": "不会进入报告"}
362+}
363+```
364+ 
365+不可用事实示例:
366+ 
367+```json
368+{
369+ "apiVersion": "preflight.openfuyao.io/fact/v1",
370+ "available": false,
371+ "error": {"code": "PERMISSION_DENIED", "message": "cannot inspect runtime"}
372+}
373+```
374+ 
375+`type` 与 resultType 对应;value 分别使用 JSON bool、整数、字符串、同类字符串/整数数组或最多32个
376+字段的 object。错误码限 NOT_FOUND、PERMISSION_DENIED、UNREACHABLE、TIMEOUT、UNSUPPORTED 和
377+PARSE_ERROR。未知字段、多份 JSON、类型不匹配或超过64 KiB 均拒绝。脚本返回 Fact 而不是
378+PASS/FAIL;用户不填写 digest,由 Host 计算观测 SHA-256。框架不接受用户提供的 raw shell、inline、
379+`bash -c`、上传、下载、隐式 sudo 或自定义环境。fileContent 原文和 object 非公开字段只存在于本次
380+内存 Fact/CEL,报告使用安全 Display/publicFields;bool、integer、string 和 list 的 value 会作为
381+实际值进入报告。脚本提供者必须审核业务逻辑与输出内容,不能输出凭据或其他敏感值。
382+ 
383+增加发布固定规则时优先复用已有 Fact;只有现有能力无法表达且有明确来源时才增加新的固定 Fact
384+或 Collector。新增 operation 必须建立独立 Host Adapter、输入规范、规则提案、SourceLock 和真实 E2E,
385+不能自动继承 init/cluster-create 规则。
386+ 
387+## 10. 威胁模型与质量属性
388+ 
389+| 风险 | 控制 |
390+|---|---|
391+| 凭据泄露 | Host 安装凭据只在 executor/client,不进入 Plan/Fact/Report;custom 内容按 Display/publicFields 投影,scalar/list 视为公开输出 |
392+| 任意代码执行 | 固定规则使用 allowlist;custom exec 禁止 raw shell/inline/上传/sudo/env,并校验权限 |
393+| 恶意或超大输入 | 严格 schema、文件大小、输出大小、CEL 长度和成本限制 |
394+| 网络误诊 | transport、auth、privilege 分层;TCP 不解释为 HTTP/TLS/auth |
395+| 单根因告警风暴 | 显式 DAG 和依赖 SKIP |
396+| 非确定性结果 | 规范化、Fact 去重、稳定排序、摘要和 renderer 单一事实源 |
397+| 超时失控 | Host 总体 context、单 Fact timeout 和有界并发 |
398+ 
399+质量属性要求:核心无全局可变状态;同输入结果确定;错误可定位;新增 Fact/规则可独立测试;schema
400+和 Report 通过版本字段演进;敏感字段默认不进入公开 DTO。
401+ 
402+## 11. 测试与验收
403+ 
404+必须覆盖:
405+ 
406+- PlanHash 规范化、Subject/Value/Source/Binding identity 和敏感信息门禁。
407+- Bundle schema、digest、SourceLock、operator/expected、DAG 和 CEL 静态校验。
408+- Collector 的零/多 Fact、identity、available/error、type/value 和 Evidence 契约。
409+- DAG 根因传播、去重、并发、稳定排序、超时和取消。
410+- 内置 operator 与 custom CEL 的正向、失败、未知、类型和成本边界。
411+- local、artifact、endpoint、Kubernetes、SSH、custom 的只读和脱敏测试。
412+- Report 完整性、Overall/退出码、动态终端宽度、中文显示和单 JSON 文档。
413+- Host 的真实 CLI、SSH、Kubernetes E2E;fake collector 只作为进程内集成测试。
414+ 
415+## 12. 参考资料
416+ 
417+- [openFuyao 统一前置检查提案](./openFuyao统一前置检查提案.md)
418+- [init 阶段检查项提案](./init阶段检查项提案.md)
419+- [cluster-create 阶段检查项提案](./cluster-create阶段检查项提案.md)
420+- [preflight-bundle-gen 提案](./preflight-bundle-gen提案.md)
@@ -7,7 +7,7 @@
7- 命令7- 命令
8 8 
9 ```shell9 ```shell
10- bke build 10+ bke build
11 ```11 ```
12 12 
13- 命令功能13- 命令功能
@@ -49,6 +49,174 @@
49 49 
5050
51 51 
52+## 统一前置检查
lihangyu
lihangyulihangyu2 天前

这里建议统一说明一下后续版本bke-preflight功能会逐步替代env-check,env-check会在下个版本退出文档然后再分别展开bke-prefight和env-check的用户文档

likedislike
53+ 
54+- 命令
55+ 
56+ ```shell
57+ bke preflight init
58+ bke preflight cluster-create
59+ ```
60+ 
61+- 命令功能
62+ 
63+ 在初始化引导节点或创建集群之前,独立执行环境检查并输出可修复报告。内置检查只读;命令不会
64+ 自动调用`bke init``bke cluster create`,也不会安装、修复、清理或写入Kubernetes资源。
65+ 如显式启用自定义`exec`,脚本行为由提供者负责审核,框架不能保证脚本业务逻辑只读。
66+ 
67+- 命令格式
68+ 
69+ 1. 使用与`bke init`相同的业务参数检查引导节点。例如:
70+ 
71+ ```shell
72+ bke preflight init --hostIP 192.0.2.10 --installConsole=false
73+ ```
74+ 
75+ 2. 检查cluster-create输入、管理集群只读依赖和目标节点:
76+ 
77+ ```shell
78+ bke --kubeconfig /path/to/kubeconfig \
79+ preflight cluster-create \
80+ -f /root/openfuyao/bkecluster.yaml \
81+ -n /root/openfuyao/bkenodes.yaml
82+ ```
83+ 
84+ 3. 输出JSON并保存报告:
85+ 
86+ ```shell
87+ bke --kubeconfig /path/to/kubeconfig \
88+ preflight cluster-create \
89+ -f /root/openfuyao/bkecluster.yaml \
90+ -n /root/openfuyao/bkenodes.yaml \
91+ --output json \
92+ --output-file /root/preflight-report.json
93+ ```
94+ 
95+- 公共参数说明
96+ 
97+ | 参数名称 | 描述 |
98+ |:---|:---|
99+ | `--output` | 输出格式,支持`text``json`,默认`text`。 |
100+ | `--output-file` | 将UTF-8详细报告写入指定文件。 |
101+ | `--preflight-config` | 完整外部`preflight.yaml`路径;不指定时使用二进制内置默认策略。 |
lihangyu
lihangyulihangyu2 天前

preflight-config里面的配置项是否应该介绍下?因为这个可以开放给用户自己配置了

likedislike
102+ | `--timeout` | 完整前置检查超时,默认`10m`,包含管理集群准备阶段。 |
103+ | `--fact-timeout` | 单个事实探测超时,默认`30s`。 |
104+ | `--max-concurrency` | 只读探针最大并发数;`0`表示自适应,显式范围为1~64。 |
105+ 
106+ `preflight init`的业务参数与`bke init`一致;`preflight cluster-create`使用`-f/--file``-n/--nodes`。全局`--kubeconfig`应放在`preflight`子命令之前。
107+ 
108+ 命令不提供`--request`、Bundle覆盖或本地Provider defaults覆盖参数。需要调整资源阈值、支持平台、
109+ 端口、条件、角色、级别或修复建议时,复制完整`preflight.yaml`并通过`--preflight-config`加载,
110+ 修改会在本次运行生效。外部YAML不能覆盖发布规则或SourceRef,但可在对应operation增加
111+ `customChecks`;未知字段或release不匹配时前置检查不启动。
112+ 
113+ 运行`bke version`取得`gitCommitID`,再从bkeadm仓库该修订下的
114+ `configs/preflight/preflight.yaml`复制完整默认文件。下面的示例只是要插入完整文件的配置片段,
115+ 不能单独保存后传给`--preflight-config`
116+ 
117+ 例如,init检查`/etc/hosts`中的IPv4或IPv6回环地址:
118+ 
119+ ```yaml
120+ operations:
121+ init:
122+ customChecks:
123+ - key: hosts-loopback
124+ description: /etc/hosts 回环地址配置
125+ expected: 包含 127.0.0.1 或 ::1 回环地址映射
126+ collector: {type: fileContent, path: /etc/hosts}
127+ expression: >-
128+ actual.matches('(?m)^\\s*(127\\.0\\.0\\.1|::1)(\\s|$)')
129+ failure: fail
130+ unknown: fail
131+ remediation: 补充回环地址映射后重试
132+ ```
133+ 
134+ `when`只能引用Plan中已有的bool key,不是CEL表达式。init自定义项不支持`roles`;cluster-create
135+ 仅支持`master``worker``etcd``all`,且`all`不能与其他角色混用。
136+ 
137+ 受控`exec`示例:
138+ 
139+ ```yaml
140+ operations:
141+ clusterCreate:
142+ customChecks:
143+ - key: runtime-health
144+ description: 容器运行时状态
145+ expected: 运行时健康
146+ collector:
147+ type: exec
148+ path: /usr/local/libexec/check-runtime
149+ args: [--format, fact]
150+ resultType: object
151+ publicFields: [runtime, healthy]
152+ expression: actual.healthy == true
153+ roles: [all]
154+ failure: fail
155+ unknown: fail
156+ remediation: 检查容器运行时服务后重试
157+ ```
158+ 
159+ 脚本成功时stdout示例:
160+ 
161+ ```json
162+ {
163+ "apiVersion": "preflight.openfuyao.io/fact/v1",
164+ "available": true,
165+ "type": "object",
166+ "value": {"runtime": "containerd", "healthy": true}
167+ }
168+ ```
169+ 
170+ 无法采集时stdout示例:
171+ 
172+ ```json
173+ {
174+ "apiVersion": "preflight.openfuyao.io/fact/v1",
175+ "available": false,
176+ "error": {"code": "PERMISSION_DENIED", "message": "cannot inspect runtime"}
177+ }
178+ ```
179+ 
180+ 自定义Collector支持`fileContent`和受控`exec``exec``resultType`支持`bool``integer`
181+ `string``stringList``integerList``object`;脚本stdout必须是单一
182+ `preflight.openfuyao.io/fact/v1` JSON。用户不填写digest,框架计算观测SHA-256。脚本必须是节点上
183+ 预装、不可被group/world写入的绝对路径普通可执行文件;不支持inline、`bash -c`、上传、隐式sudo
184+ 或自定义环境。脚本文件和stdout各最大64 KiB。object必须声明`publicFields`,只有这些字段
185+ 进入报告;fileContent原文不进入报告。不可用错误码支持`NOT_FOUND``PERMISSION_DENIED`
186+ `UNREACHABLE``TIMEOUT``UNSUPPORTED``PARSE_ERROR`。未知字段、多份JSON或类型不匹配会被拒绝。
187+ bool、integer、string和list的value会作为实际值进入报告,脚本不得输出密码、Token或其他敏感值。
188+ 
189+ 端口遵循“显式CLI/业务YAML > policy fallback”。例如显式设置`--kubernetesPort`时检查该端口,否则使用外部policy的`defaultPort`。policy只影响本次检查,不修改安装参数。
190+ 
191+ `cluster.yaml``nodes.yaml`的schema、类型或本地业务校验失败时,报告目标列显示路径式字段,例如`cluster.spec.clusterConfig.cluster.networking.podSubnet``nodes[0].spec.ip`;YAML语法错误保留文件和行号。
192+ 
193+- 报告说明
194+ 
195+ 文本控制台按“状态、检查项、目标、期望、实际、原因及建议”展示FAIL/WARN和运行问题。目标会指出具体节点及端口、路径或来源。完整报告保留PASS、FAIL、WARN和所有SKIP,包括依赖阻塞、策略跳过及未完成项。JSON输出为单一JSON文档,进度信息只写入标准错误。
196+ 
197+- 退出码
198+ 
199+ | 退出码 | 含义 |
200+ |---:|---|
201+ | `0` | 所有适用检查通过。 |
202+ | `2` | 存在WARN,或总体结论为SKIP(无适用项或全部跳过);需要人工确认。 |
203+ | `3` | 存在环境FAIL。 |
204+ | `4` | 输入或Bundle错误,前置检查未启动。 |
205+ | `5` | SDK、Adapter或collector内部错误。 |
206+ | `124` | 总体超时。 |
207+ | `130` | 用户取消。 |
208+ 
209+- 注意事项
210+ 
211+ - 先修复FAIL并确认WARN,再单独执行对应安装命令;preflight成功不会自动开始安装。
212+ - 来源检查仅建立到`host:port`的TCP连接,不代表HTTP、TLS、认证或制品下载成功。
213+ - v1 SSH检查不校验host key,只能证明会话建立,不能证明目标节点身份;应在可信网络中执行,
214+ 不能把认证成功解释为已建立host-key信任。
215+ - 脚本和流水线应直接传入与业务命令一致的flags,并使用`--output json`读取结构化结果。
216+ - `PASS`只表示报告中的适用检查在当时满足当前Bundle;它不代表后续环境不会变化,也不保证安装一定成功。需要审计时请同时保存`planHash``bundleDigest`和完整报告。
217+ - 报告可能包含节点地址、路径和来源定位信息。分享报告前应按组织要求检查脱敏;密码、Token、私钥和完整kubeconfig不应出现在报告中。
218+ - 本命令当前只覆盖init和cluster-create,不覆盖build。
219+ 
52## 初始化引导节点220## 初始化引导节点
53 221 
54- 命令222- 命令
@@ -28,7 +28,8 @@
28- 推荐准备两台机器,分别承担引导节点与业务集群节点角色;也可共部署于同一台机器(此时将同时运行 K3s 与 Kubernetes,可能相互影响,不推荐)。28- 推荐准备两台机器,分别承担引导节点与业务集群节点角色;也可共部署于同一台机器(此时将同时运行 K3s 与 Kubernetes,可能相互影响,不推荐)。
29- 引导节点的openFuyao管理面首次登录时,用户名为admin,密码为test@1234。首次登录后需要修改用户名和密码。使用的https协议,web服务端口默认为30010。29- 引导节点的openFuyao管理面首次登录时,用户名为admin,密码为test@1234。首次登录后需要修改用户名和密码。使用的https协议,web服务端口默认为30010。
30- 业务集群节点的openFuyao管理面首次登录时,用户名为admin,密码为test@1234。首次登录后需要修改用户名和密码。使用的https协议,web服务端口默认为31616。30- 业务集群节点的openFuyao管理面首次登录时,用户名为admin,密码为test@1234。首次登录后需要修改用户名和密码。使用的https协议,web服务端口默认为31616。
31-- 建议您的节点环境为干净的操作系统环境安装任何docker与Kubernetes组件否则可能发生版本冲突导致安装失败。如需在存量环境试验性安装,可下载孵化期工具[env-check](https://gitcode.com/openFuyao/sig-installation/blob/9aff806a5708b0ad901e1a3382e41bcb07615f48/docs/zh/user_guide/cluster_installation_deployment/environment_precheck_tool_user_guide.md)进行环境校验31+- 建议在执行`bke init`前使用相同业务参数运行`bke preflight init`;在执行`bke cluster create`前运行`bke preflight cluster-create -f <集群配置> -n <节点配置>`。修复`FAIL`并确认`WARN`后再执行安装命令。内置检查只读运行自动安装、修复或清理;体参数和退出码请参见[命令参考](../appendix/command_reference.md#统一前置检查)。
32+- 建议您的节点环境为干净的操作系统环境,未安装任何docker与Kubernetes组件,否则可能会发生版本冲突导致安装失败。如需额外查询或清理历史残留、检查冲突程序或比较节点时钟,可使用旧[envCheck工具](./environment_pre_check_tool_guide.md)。该工具与只读的`bke preflight`职责不同。
32- 待安装集群节点的时间需要确保和引导节点的时间一致,时间差上限为10s。33- 待安装集群节点的时间需要确保和引导节点的时间一致,时间差上限为10s。
33- 可选:如需使用自定义CA证书来签发Kubernetes集群内所有组件的证书,以满足企业级安全合规要求,可在引导节点初始化之前配置自定义证书。详细操作请参考[自定义集群证书使用指导](../bootstrap_cluster_configuration/using_custom_cluster_certificates.md)。34- 可选:如需使用自定义CA证书来签发Kubernetes集群内所有组件的证书,以满足企业级安全合规要求,可在引导节点初始化之前配置自定义证书。详细操作请参考[自定义集群证书使用指导](../bootstrap_cluster_configuration/using_custom_cluster_certificates.md)。
34- 可选:如需配置自定义仓库进行安装请参见[自定义仓库使用指导](../bootstrap_cluster_configuration/custom_repository_configuration_guide.md)。35- 可选:如需配置自定义仓库进行安装请参见[自定义仓库使用指导](../bootstrap_cluster_configuration/custom_repository_configuration_guide.md)。
@@ -1,5 +1,27 @@
1# 环境前置检查1# 环境前置检查
D
Ddingtingyu2 天前

1、建议环境前置检查分成2个大章节

  • bke内置前置检查工具(或其他官方名字)
  • envcheck

2、bke内置前置检查工具 内容需包括: bke内置的统一前置检查工具的

3、envcheck章节,在开头处说明下,因v26.09版本提供了bke内置前置检查工具,此工具功能更全面或其他可优化替代envcheck。envcheck在v26.12版本将不再维护并下架。

likedislike
2 2 
3+## 与统一前置检查的关系
lihangyu
lihangyulihangyu2 天前

整体上bke-preflight的文档格式可以参考bkeadm preflight或者openshift的前置检查工具文档

likedislike
4+ 
5+新版本安装流程优先使用bke内置的统一前置检查:
6+ 
7+```bash
8+# 使用与bke init相同的业务参数
9+bke preflight init --hostIP 192.0.2.10
10+ 
11+# 使用与bke cluster create相同的集群和节点文件
12+bke --kubeconfig /path/to/kubeconfig \
13+ preflight cluster-create -f bkecluster.yaml -n bkenodes.yaml
14+```
15+ 
16+| 能力 | `bke preflight` | `envCheck` |
17+|---|---|---|
18+| 当前统一规则 | init和cluster-create的固定发布规则、来源和依赖 | 不使用当前PreflightBundle,不应替代统一检查 |
19+| 环境变更 | 只读;不安装、修复、清理或写入Kubernetes | `clean`可以删除配置中指定的文件 |
20+| 历史残留/时钟 | 不作为当前统一规则,避免存量环境误报 | 可按用户配置查询/清理残留、检查程序和比较时钟 |
21+| 报告 | 终端表格及完整text/JSON,包含期望、实际、原因和建议 | 旧text/JSON/HTML报告 |
22+ 
23+安装前应先运行对应的`bke preflight`,修复FAIL并确认WARN。只有确实需要处理历史残留或时钟等兼容场景时才使用本页的`envCheck`;不要把`envCheck`结果解释为当前Bundle的统一前置检查结论。
24+ 
3## 背景信息25## 背景信息
4 26 
5用户在使用安装部署工具的过程中发现,由于环境中可能存在其他软件残留的配置文件,以及部分和规格中冲突的应用程序,导致安装部署过程异常或失败。为了保障安装部署的成功运行,需要构建一个前置环境检查工具,确保安装部署之前,环境是可用的。目前工具已实现以下功能。27用户在使用安装部署工具的过程中发现,由于环境中可能存在其他软件残留的配置文件,以及部分和规格中冲突的应用程序,导致安装部署过程异常或失败。为了保障安装部署的成功运行,需要构建一个前置环境检查工具,确保安装部署之前,环境是可用的。目前工具已实现以下功能。
@@ -22,7 +44,8 @@
22 44 
23## 使用限制45## 使用限制
24 46 
25-47+- `envCheck clean`和`envCheck clean --force`会删除配置中`paths`指定的文件,不属于只读前置检查执行前必须确认路径、备份和恢复方案;生产环境不建议使用`--force`。
48+- `envCheck`中的残留文件、冲突程序和时钟规则是用户配置的历史兼容能力,不代表当前bke/Provider发布契约。
26 49 
27## 使用教程50## 使用教程
28 51