mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): materialize offline deployment locks
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
最新增量证据(2026-08-16):
|
||||
|
||||
- D-337/ADR-0429(已接受):D-336 的 durable release set 现在可以离线物化为最终部署 authority,而不是由运维者手工复制 digest。可信工作站上的 `ql3-deployment-lock-contract.cjs` 不联网、不连接 Kubernetes API、不执行 rollout:Local/All 生成绑定 release-set digest、唯一 Local `@sha256:` 与显式 root policy 的 canonical selection;Cluster/All 先消费 `kubectl kustomize` 的最终多文档 YAML,再只改写封闭的 Pod/Deployment/StatefulSet/DaemonSet/ReplicaSet/Job/CronJob container 字段和 exact Plugin Package admission ConfigMap,生成带输入/输出 digest、各 role occurrence、release annotation 与 self digest 的 locked manifest/report。调用方必须显式声明 required role,未知位置的完整 role authority、畸形 container image、缺失角色、YAML alias/cycle/非 mapping、超限或覆盖输出全部失败关闭;audit 从原 release set 与原 render byte-exact 重建。采用 post-render 是因为真实原型证明外层 Kustomize component 不能可靠覆盖内层已选 repository/digest,且 `images` transformer 不处理 ConfigMap `data.image`。本机 kubectl 1.36.1/Kustomize 5.8.1 已真实渲染 CloudNativePG Core、Cluster AI、Worker node 与 Plugin Package Executor 四类清单,内层零 digest 均被同一 release set 的精确引用替换;定向 deployment-lock 11/11、发布链路联动 101/101,静态审计冻结 224 个 YAML、31 个直接 role image 引用与两个 admission authority。工具只在工作站运行,低配路由器只消费 Local selection,不新增 Node/YAML/Kubernetes/registry 工具、package、依赖、常驻进程或资源;Cluster 也不新增 controller/webhook/CRD/RBAC。完整 backend 共 1,295 项,1,293 pass/2 条件 skip/0 fail;18-package clean build/test 退出 0,package boundary 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,10 项架构/部署审计与 14 档 Local artifact 全部 compatible。默认 Edge/Standalone 为 2,589,890/2,589,968 bytes,application+AI 为 4,493,043/4,493,175 bytes,MCP 为 7,315,930/7,316,038 bytes;Cluster Admin pack 保持 250 files、271,238-byte tarball、1,690,196-byte unpacked。本 Gate 不改数据库或 HA 拓扑。
|
||||
- D-336/ADR-0428(已接受;公开发布结果待实际 tag):D-335 的 90 天 workflow artifact 不再是长期唯一发布入口。完整 release set 现以单层 OCI artifact 发布到专用 `ghcr.io/<owner>/qinglong3-release-catalog`,固定 artifact/file media type、basename、四项 annotation 和 byte-exact round trip;`v<version>-<scope>` 仅作发现且 authority 明确为 `none`,部署权威是验证后的 catalog `@sha256:` immutable reference。发布后先按 digest 取回并逐字节比较、审计 raw manifest,再为该 digest 生成 exact workflow identity 的 keyless Cosign signature 与绑定 source tag/revision 的 GitHub OCI provenance;验证成功后才生成 canonical receipt 并为 receipt 增加 file provenance。release-set 新增不依赖短期 candidate/image-record 的 standalone inspect,重算结构、身份、Local/Cluster 镜像闭包与 self digest,同时显式声明未重放 source records。低配路由器可在可信工作站完成 registry/签名/provenance/Node 验真,只消费 `local` JSON 与镜像 digest,设备不增加工具、package、依赖或常驻资源;Cluster 使用同一 catalog 锁定 control、control-ai、worker、admin 四角色。真实本机 `ocidir://` 实验确认同一文件来自两个不同绝对目录时,`--file-title --strip-dirs` 产生相同 manifest digest `sha256:0443422e34edd448499a61f4580b01b9578dc35a117668c948c51a16638e4e9d`,immutable get 与源文件逐字节一致。定向发布契约/静态 workflow/Console 联动测试 93/93;backend 1282 项为 1280 pass、2 条件 skip、0 fail;18-package clean build/test 退出 0,package boundary 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,release version、dependency、Edge import、Cluster/Worker deployment、image release、Local image 与 Console distribution 审计全部 compatible。14 档 Local artifact 均 compatible,默认 Edge/Standalone 为 2,589,890/2,589,968 bytes,MCP 为 7,315,930/7,316,038 bytes;Cluster Admin pack 保持 250 files、271,238-byte tarball、1,690,196-byte unpacked。本 Gate 无数据库/HA 拓扑变化,复用 D-331/D-333 PostgreSQL 18.6 arm64 142/142、timeline `1→2` 基线。公开 GHCR push、签名和 attestation 尚未执行,且 GHCR 保留/删除仍属于组织治理,因此不宣称 catalog 为 WORM 或已完成线上发布。
|
||||
- D-335/ADR-0427(已接受;公开发布结果待实际 tag):发布矩阵不再让每个镜像验证成功后独立写 version/source tag。每个 publisher 只产生不可变 digest,在远端 manifest、Cosign、四类 GitHub attestation 与适用的 Local rollout 全部验证后生成绑定同一 candidate/scope/source/owner/repository/platform/digest 的 canonical image record;唯一 release-set 终态 job 只在完整 publish matrix 成功后下载 exact `run_id/run_attempt` record,重新生成 candidate,并要求 Local 一镜像、Cluster 四镜像或 All 五镜像集合无遗漏、无重复、顺序一致。独立审计通过后才统一 promotion,写前回读全部 source digest/既有 tag、冲突失败、缺失才 copy、写后再验 digest;明确不宣称 GHCR 跨仓库原子性,以 `verify_exact_digest_then_continue` 支持同源幂等恢复。最终 `qinglong/release-set@v1` 同时冻结 deployment family、五类可选镜像、image-record digest 和 `@sha256:` 引用,获得 GitHub file provenance 并作为 90 天 deployment digest-lock artifact 发布。Edge/Standalone 只消费 `local` set,Cluster 只消费四角色 set,`all` 不把两族运行时耦合;不新增 package、生产依赖、Pod、controller、listener、timer、watcher、数据库、migration、SQL、Pool 或低配设备常驻开销。定向 contract/workflow 回归 73/73,联动发布/Console distribution 回归 77/77;backend 1,264 pass/2 条件 skip/0 fail,18-package clean build/test 退出 0,package boundary 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,dependency、Edge import、Cluster/Worker deployment、image release 与 Local image 审计均 compatible。14 档 Local artifact 全部 compatible,默认 Edge/Standalone 精确保持 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 为 4,493,043/4,493,175 bytes,MCP 为 7,315,930/7,316,038 bytes;Cluster Admin pack 保持 250 files、271,238-byte tarball、1,690,196-byte unpacked。本 Gate 无数据库/HA 拓扑变化,复用 D-331/D-333 PostgreSQL 18.6 arm64 142/142、timeline `1→2` 基线;公开 tag 尚未执行,因此不宣称真实 GHCR promotion 或线上 attestation 已成功。
|
||||
- D-334/ADR-0426(已接受):根级 canonical `ql3-release.json` 现在是唯一 QingLong 3 release identity authority,精确冻结 3.x SemVer、Node 24.18.0/engine、18-package 边界和 legacy 2.x 排除事实;发布候选、四组容器、Cluster/Worker/Console 部署、Local/Cluster image audit、CloudNativePG、物理 Edge 与外部恢复审计均改为读取同一 authority,candidate contract 额外绑定 identity schema 与 SHA-256。共享 CI 新增 `audit:release-version:ql3`,失败关闭 18 个 workspace、四组 build/runtime manifest+lock、Dockerfile Node/version label 与 242 个部署文本文件中的 32 个 image reference/36 个版本 occurrence。维护者升级版本必须走 closed `audit|plan|apply`:plan 只接受严格递增 exact v3 SemVer并生成 no-replace `0600`、逐文件 path/mode/replacement/before-after bytes+digest 和自身 digest;apply 先全量预检 65 文件/83 处替换,再用同目录确定性临时文件、fsync+rename 逐文件收敛,允许 source/target 混合状态原 plan 幂等恢复并生成 digest-bound report,绝不修改 legacy 根 2.x、自动 commit/tag/push 或宣称跨文件单事务。实现不新增 workspace package、生产依赖、数据库、migration、SQL、Pool、Pod、listener、timer、watcher 或任何低配/集群常驻开销。定向回归 177/177,backend 1,254 pass/2 条件 skip/0 fail,18-package clean build/test 退出 0;package boundary 保持 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,dependency、Edge import、Cluster deployment、image release 与 Local image 审计均 compatible。14 档 Local artifact 全部 compatible,默认 Edge/Standalone 精确保持 2,589,890/2,589,968 bytes、315 files、56 modules,application+AI 为 4,493,043/4,493,175 bytes,MCP 为 7,315,930/7,316,038 bytes;Cluster Admin pack 保持 250 files、271,238-byte tarball、1,690,196-byte unpacked。本 Gate 无数据库/HA 拓扑变化,复用 D-331/D-333 PostgreSQL 18.6 arm64 142/142、timeline `1→2` 基线;完整回归未发现数据库或部署拓扑漂移。
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# ADR-0429:离线 Release-set Deployment Lock 物化
|
||||
|
||||
- 状态:Accepted
|
||||
- 日期:2026-08-16
|
||||
- 关联 RFC:QL-RFC-0001 D-03、D-14、D-333、D-334、D-335、D-336、D-337
|
||||
|
||||
## 上下文
|
||||
|
||||
ADR-0428 让部署者能够从持久 OCI catalog 取得并独立验证完整 release set,但验证后的
|
||||
`images[].reference` 仍需人工写入 Local Compose 或 Kubernetes 清单。Cluster 的 Kustomize 结构包含嵌套 overlay;当内层
|
||||
已经把镜像转换为另一个 repository 和 digest 时,外层 image transform 不保证再次覆盖它。Plugin Package admission
|
||||
ConfigMap 还把短生命周期 Admin 镜像 authority 保存于 `data.image`,不属于 Kustomize 内建 `images` transformer 的处理面。
|
||||
因此,“release set 已验证”与“最终 apply 的清单确实只消费该 release set”之间仍存在人工复制和遗漏窗口。
|
||||
|
||||
同一解决方案还必须保持部署形态隔离。低配路由设备只能承担 Local 单镜像消费,不能为 Cluster 的渲染工具、YAML parser
|
||||
或 Kubernetes client 付出安装和常驻资源;Cluster 工作站则需要处理 Core、AI、Worker 与短生命周期 Admin 多种独立清单,
|
||||
但生成工具不能因此获得 Kubernetes mutation authority。
|
||||
|
||||
## 决策
|
||||
|
||||
1. 新增独立的 `ql3-deployment-lock-contract.cjs` 工作站工具。输入只能是已通过 standalone inspection 的 canonical
|
||||
release set,以及显式 release identity;所有模式均不访问网络、不读取 registry、不连接 Kubernetes API、不执行
|
||||
rollout。
|
||||
2. Local 模式只接受 `local|all` scope,并生成 canonical
|
||||
`qinglong/local-compose-release-image@v1` selection。输出绑定 release-set digest、精确 Local digest reference 和显式
|
||||
`allowRootService` boolean;它不修改 Compose,也不启动服务。低配设备只消费该选择结果,不安装 materializer。
|
||||
3. Kubernetes 模式只接受 `cluster|all` scope。运维者先执行 `kubectl kustomize`,materializer 再处理最终多文档 YAML,
|
||||
从而穿透任意嵌套 overlay 的 transform 顺序。调用者必须按发布顺序显式声明当前清单必含的 role;缺少任一 required role
|
||||
时失败关闭。
|
||||
4. 可改写面封闭为 Pod、Deployment、StatefulSet、DaemonSet、ReplicaSet、Job、CronJob 的
|
||||
`containers`、`initContainers`、`ephemeralContainers`,以及 exact-name
|
||||
`ql3-plugin-package-secret-action-admission` ConfigMap 的 `data.image`。完整 QingLong role tag/digest 出现在其他位置时拒绝;
|
||||
已知 container 中的裸名、未知 role-like name 或畸形引用同样拒绝。非 QingLong sidecar 保持原样。
|
||||
5. 每个被改写的资源和适用的 Pod template 写入 release-set digest、source revision、version annotation。输出 report 固定
|
||||
输入/输出 SHA-256、资源数、改写资源数、各 role reference/出现次数、admission authority 次数与 no-network/no-mutation
|
||||
结论,并以 self digest 封闭。
|
||||
6. `local-audit` 与 `kubernetes-audit` 从原 release set 和原始 render 完整重建期望输出,要求 byte/object exact matching,
|
||||
不把“输出中看见 digest”当作充分证明。输入限制为 canonical absolute、非 symlink、有界 UTF-8 regular file;JSON 必须
|
||||
canonical,YAML 禁止 alias/cycle、非 mapping resource、过深/过多/过大结构。所有输出以 0600、no-replace 创建。
|
||||
7. 仓库静态审计固定 Cluster/Worker 的 224 个 YAML 文件、31 个直接 role image 引用与两个 admission ConfigMap authority。
|
||||
新增或移动镜像 authority 必须先扩展受支持处理面与负向测试,不能静默绕过 post-renderer。
|
||||
|
||||
## 部署与资源影响
|
||||
|
||||
- Local/Edge/Standalone runtime、镜像、workspace package、生产依赖、进程、listener、timer、watcher、数据库连接和内存预算
|
||||
均不变化。Node、`js-yaml`、registry/Kubernetes 工具只存在于可信维护工作站;路由器接收一个 Local selection 与一个
|
||||
immutable image。
|
||||
- Cluster 不新增 controller、admission webhook、CRD、ServiceAccount 或 API 权限。materializer 在 apply 之前退出;真正的
|
||||
`kubectl apply -f locked.yaml` 是独立、显式、可审阅的运维步骤。
|
||||
- 本决策不修改 schema、migration、SQL、PostgreSQL role、Pool、连接或 HA 拓扑,因此不制造新的数据库发布证据要求。
|
||||
|
||||
## 被拒绝的替代方案
|
||||
|
||||
### 在每层 Kustomize overlay 增加 image component
|
||||
|
||||
拒绝。外层 component 不能可靠覆盖内层已转换的 repository/digest,且 Kustomize `images` 不处理 ConfigMap 中的 Admin
|
||||
authority;继续堆叠 component 会让最终 authority 取决于难以审计的 transform 顺序。
|
||||
|
||||
### 直接修改仓库中的零 digest 占位符
|
||||
|
||||
拒绝。它把环境私有 release identity 写回共享源码,容易产生脏工作区、错误复用和漏改,而且不能证明多个清单来自同一
|
||||
release set。
|
||||
|
||||
### 在 Cluster 内运行常驻 image policy controller
|
||||
|
||||
拒绝。当前缺口可以在工作站离线关闭。新增 controller/webhook 会引入可用性、升级、证书和 API authority 故障域,也会
|
||||
错误地把发布供应链验真变成集群运行时依赖。
|
||||
|
||||
### 让路由器自行验证和物化
|
||||
|
||||
拒绝。低资源设备没有必要承担 Node、YAML、registry、Cosign、GitHub CLI 或 Kubernetes 工具链;可信工作站可以生成并
|
||||
审计更小的 Local selection,而设备仍以 digest 消费。
|
||||
|
||||
## 验证
|
||||
|
||||
- deployment-lock 契约覆盖 Local/All selection、Cluster/All materialization、全部 workload container 类型、固定 admission
|
||||
ConfigMap、required role closure、unknown/malformed authority、release/source/report/render drift、duplicate YAML、非
|
||||
mapping、closed CLI、symlink、0600 与 no-replace;定向测试 11/11;
|
||||
- 本机 `kubectl v1.36.1`/Kustomize `v5.8.1` 真实渲染 CloudNativePG Core、Cluster AI、Worker node 与 Plugin Package
|
||||
Executor 四类清单后,post-render 全部生成 release-set exact digest,内层全零占位 digest 均消失;
|
||||
- 发布契约、release set/catalog、静态 workflow 与 deployment-lock 联动测试 101/101,部署面审计确认 224 个 YAML、31 个
|
||||
直接 role image 引用和两个 admission authority;
|
||||
- 完整 backend 共 1,295 项,1,293 pass/2 条件 skip/0 fail;18-package clean build/test 退出 0,package boundary 仍为
|
||||
18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,release version、dependency、Edge import、Cluster/Worker
|
||||
deployment、image release、Local image、Console distribution 与 deployment-lock surface 等 10 项审计全部 compatible;
|
||||
- 14 档 Local artifact 全部 compatible:默认 Edge/Standalone 为 2,589,890/2,589,968 bytes,application+AI 为
|
||||
4,493,043/4,493,175 bytes,MCP 为 7,315,930/7,316,038 bytes;Cluster Admin pack dry-run 保持 250 files、
|
||||
271,238-byte tarball、1,690,196-byte unpacked。
|
||||
@@ -432,6 +432,7 @@
|
||||
| [ADR-0426](./ADR-0426-source-derived-release-version-transition.md) | Source-derived QingLong 3.0 Release Version Transition | Accepted |
|
||||
| [ADR-0427](./ADR-0427-complete-cross-image-release-set.md) | 完整跨镜像发布集与部署 Digest Lock | Accepted |
|
||||
| [ADR-0428](./ADR-0428-durable-oci-release-catalog.md) | 持久化 OCI Release Catalog 与独立部署验真 | Accepted |
|
||||
| [ADR-0429](./ADR-0429-offline-release-set-deployment-lock-materialization.md) | 离线 Release-set Deployment Lock 物化 | Accepted |
|
||||
|
||||
## 规则
|
||||
|
||||
|
||||
@@ -88,6 +88,94 @@ gh attestation verify "${release_set}" \
|
||||
`inspect` 会重算 release-set self digest 并验证结构、身份、镜像闭包和 family,但不会重放发布时已经过期的 image
|
||||
records;其输出必须保持 `sourceRecordsReplayed:false`。
|
||||
|
||||
## 生成离线 deployment lock
|
||||
|
||||
`inspect` 成功后,不要手工复制 digest,也不要直接修改仓库中的 Kustomize 占位符。deployment-lock
|
||||
materializer 在可信工作站离线运行,只读取已经验证的 release set 与本地清单;它不访问 registry、不连接 Kubernetes
|
||||
API,也不会执行 `kubectl apply`。
|
||||
|
||||
### Local / Compose
|
||||
|
||||
对 `local` 或 `all` scope 生成一个 canonical、0600、no-replace 的 service selection:
|
||||
|
||||
```sh
|
||||
selection="$(pwd)/qinglong3-local-selection-${version}.json"
|
||||
|
||||
node scripts/ql3-deployment-lock-contract.cjs \
|
||||
--mode=local-create \
|
||||
--version="${version}" \
|
||||
--source-revision="${source_revision}" \
|
||||
--source-ref="${source_ref}" \
|
||||
--release-scope="${scope}" \
|
||||
--repository-owner="${owner}" \
|
||||
--release-set="${release_set}" \
|
||||
--allow-root-service=false \
|
||||
--output="${selection}"
|
||||
|
||||
node scripts/ql3-deployment-lock-contract.cjs \
|
||||
--mode=local-audit \
|
||||
--version="${version}" \
|
||||
--source-revision="${source_revision}" \
|
||||
--source-ref="${source_ref}" \
|
||||
--release-scope="${scope}" \
|
||||
--repository-owner="${owner}" \
|
||||
--release-set="${release_set}" \
|
||||
--allow-root-service=false \
|
||||
--selection="${selection}"
|
||||
```
|
||||
|
||||
把已审计的 `service.image` 和 `service.allowRootService` 交给现有 Local private prepare/rollout 入口。selection
|
||||
本身不修改 Compose 文件,也不启动容器。是否允许 root service 必须显式给出,不能由设备默认值推断。
|
||||
|
||||
### Kubernetes / Cluster / Worker
|
||||
|
||||
先用已审核 overlay 生成普通多文档 YAML,再把它作为 post-render 输入。以下是 Cluster Core 示例;AI、Worker、Admin
|
||||
清单分别把 `required-images` 设为 `control-ai`、`worker`、`admin`,组合清单则按发布顺序使用
|
||||
`control,control-ai,admin,worker`:
|
||||
|
||||
```sh
|
||||
rendered="$(pwd)/ql3-cluster-rendered.yaml"
|
||||
locked="$(pwd)/ql3-cluster-locked.yaml"
|
||||
lock_report="$(pwd)/ql3-cluster-deployment-lock.json"
|
||||
|
||||
kubectl kustomize deploy/kubernetes/ql3-cluster/overlays/cloudnative-pg > "${rendered}"
|
||||
|
||||
node scripts/ql3-deployment-lock-contract.cjs \
|
||||
--mode=kubernetes-create \
|
||||
--version="${version}" \
|
||||
--source-revision="${source_revision}" \
|
||||
--source-ref="${source_ref}" \
|
||||
--release-scope="${scope}" \
|
||||
--repository-owner="${owner}" \
|
||||
--release-set="${release_set}" \
|
||||
--manifest="${rendered}" \
|
||||
--required-images=control \
|
||||
--output-manifest="${locked}" \
|
||||
--output-report="${lock_report}"
|
||||
|
||||
node scripts/ql3-deployment-lock-contract.cjs \
|
||||
--mode=kubernetes-audit \
|
||||
--version="${version}" \
|
||||
--source-revision="${source_revision}" \
|
||||
--source-ref="${source_ref}" \
|
||||
--release-scope="${scope}" \
|
||||
--repository-owner="${owner}" \
|
||||
--release-set="${release_set}" \
|
||||
--manifest="${rendered}" \
|
||||
--locked-manifest="${locked}" \
|
||||
--report="${lock_report}" \
|
||||
--required-images=control
|
||||
```
|
||||
|
||||
materializer 只改写 Pod、Deployment、StatefulSet、DaemonSet、ReplicaSet、Job、CronJob 的
|
||||
`containers`/`initContainers`/`ephemeralContainers`,以及固定名称
|
||||
`ql3-plugin-package-secret-action-admission` ConfigMap 的 `data.image`。每个改写资源及其 Pod template 都绑定
|
||||
release-set digest、source revision 与 version annotation;未知位置的完整 QingLong role image authority、畸形已知
|
||||
container image、缺少 required role、YAML alias/cycle/非 mapping、超限输入或已有输出文件都会失败关闭。
|
||||
|
||||
审计成功并完成人工差异检查后,才由有权限的独立步骤执行 `kubectl apply -f "${locked}"`。不要直接 apply
|
||||
`${rendered}`,也不要使用 `kubectl apply -k` 绕过 deployment lock。
|
||||
|
||||
## 准入检查
|
||||
|
||||
1. 只接受已验证 Cosign exact workflow identity 与 GitHub source tag/revision provenance 的 catalog immutable
|
||||
@@ -95,15 +183,17 @@ records;其输出必须保持 `sourceRecordsReplayed:false`。
|
||||
2. `schema` 必须为 `qinglong/release-set@v1`;`release.version`、`release.sourceRef`、
|
||||
`release.sourceRevision`、`release.scope` 必须与变更单一致。
|
||||
3. 镜像集合必须与上表精确相等;每个 `reference` 必须是 digest reference,且 owner/repository 与部署目标一致。
|
||||
4. Kubernetes overlay 用 `newName` 加 digest 或等价的 immutable image reference;不得把生产 placeholder 改成
|
||||
`newTag`。Local compose/rollout 同样固定 `@sha256:`。
|
||||
4. Kubernetes 必须先渲染 overlay,再用离线 post-render materializer 生成和复验 locked manifest;嵌套 overlay 的
|
||||
`newName`/digest 不是最终 authority。Local 必须生成并审计 service selection。两族最终都只能消费 release set 中的
|
||||
`@sha256:` reference。
|
||||
5. rollout 前再次确认 catalog receipt/immutable reference 与已检查文件一致。version/source/catalog tag 都只能用于
|
||||
发现;部署始终以 release set 中的镜像 digest 为准。
|
||||
|
||||
## 低资源设备
|
||||
|
||||
路由器或其他低配 Edge 设备不需要安装 Node、regctl、Cosign 或 GitHub CLI。维护者在可信工作站完成上述 ceremony,
|
||||
再向设备传输已检查的 canonical JSON,并只把 `local` family 的 immutable image reference 写入 compose/rollout。
|
||||
路由器或其他低配 Edge 设备不需要安装 Node、regctl、Cosign、GitHub CLI、Kustomize 或 materializer。维护者在可信工作站
|
||||
完成上述 ceremony 和 Local selection 审计,再向设备传输已检查的 canonical JSON,并只把 `local` family 的 immutable
|
||||
image reference 写入 compose/rollout。
|
||||
设备不下载 Cluster 四镜像,也不加载 Kubernetes、CloudNativePG、PostgreSQL driver 或 Worker 私有发布证据。
|
||||
|
||||
如果设备本身不运行容器 registry client,可由工作站按 digest 拉取并通过既有离线交付渠道传送镜像;离线包的哈希与
|
||||
|
||||
Reference in New Issue
Block a user