跳转到内容

模块 VII — 部署与集成

部署定义、计划、apply、回滚、退役、executor 设置和接线台账是 Business 功能。Community 对这些 API 路由返回 501,并隐藏该命令组。已保存的定义、修订、接线和操作会保留在数据库和灾难恢复备份中。以下各节描述 Business 的行为。

模块 VII 是唯一会变更客户基础设施的模块——产品的其余每个部分都是 read-first(先读取)的。 它以声明式、版本化、可回滚的操作来预置、更新和退役智能体与 MCP 服务器,并声明智能体到达 企业资源时所使用的连接方式与所引用的身份。正因为它会实施操作,其安全标准在整个产品中最高, 而实时执行被保持在一道 deny-closed 接缝之后,直到操作员显式将其预置为止。

先规划与治理,然后(也许)apply

Section titled “先规划与治理,然后(也许)apply”

生命周期为 plan → apply → verify → retire,将期望状态与实际状态进行协调。真正关键的 区分是声明 ≠ 变更:

  • 声明期望状态——创建、更新、回滚一份定义(也可通过 manage-as-code 的 olivares_deployment 资源进行)——仅限于 control plane(控制平面),绝不触及基础设施。
  • plan 是纯粹的 dry-run 差异计算;verify 检查漂移并刷新快照。两者都不会变更。
  • apply 与 retire 是仅有的会变更的操作。它们是两阶段且 **deny-by-default(默认拒绝)**的: 第一阶段计算差异并请求一项绑定到 plan hash 的人工审批,期间不改变任何东西;第二阶段仅在审批为 approved 且 plan hash 仍然匹配时才继续——任何其他状态(pending、expired、rejected、无门控、 陈旧的 plan)都会被拒绝并记录。重新指定会改变 hash 并使审批失效(anti-TOCTOU,防时序攻击)。

会变更的 apply/retire 默认不是实时的。执行接缝(Executor) 是 deny-closed 的:在没有预置 executor 的情况下,apply/retire/plan/verify 会以 503 fail closed (失败即拒绝)——control plane 可以声明期望状态,但无法协调到实际基础设施。一个真正的引擎 (Tofu/Terraform、GitOps、Kubernetes、Docker、Nomad、Crossplane)外加一个短时、按操作、经过证明的 凭据来源,只在操作员配置时才会接入;在此之前,该模块绝不会静默地实施操作。

在管理员接入执行器之前,Deploy 只保存部署定义,不会更改任何基础设施。接入步骤如下:

  1. 编写一个 JSON 文件,为每个部署目标运行时(docker、k8s、nomad、tofu、terraform、 gitops 或 crossplane)写一个块,并加上一个 credential 块。只有文件中列出的运行时会被接入。 同一主机上的 Docker 示例:

    {
    "docker": { "socket_path": "/var/run/docker.sock" },
    "credential": {
    "kind": "file",
    "path_template": "/run/olivares/deploy/{env}-{mode}.token",
    "ttl_seconds": 900
    }
    }

    每次操作时,Olivares 从 path_template 读取一个短期令牌:{env} 是定义的环境,{mode} 是 read(计划、校验)或 write(应用、退役)。该目录由你已在运行的工具(例如 Vault Agent 或 SPIFFE 辅助程序)创建,令牌文件也由它写入并轮换。没有令牌时,每个操作都会被拒绝。对于 Docker,服务用户 olivares 还必须能打开该套接字;加入 docker 组即授予它对该主机的 root 级访问权限。

  2. 让 Olivares 指向该文件。使用 deb 或 rpm 软件包时,在 /etc/olivares/olivares.env 中加入这一行:

    终端窗口
    OLIVARES_DEPLOY_EXECUTOR_CONFIG=/etc/olivares/deploy-executor.json

    用户 olivares 必须能读取该 JSON 文件,例如属主为 root:olivares、权限为 0640。

  3. 用 sudo systemctl restart olivares 重启 Olivares。如果文件无法读取或内容无效,Olivares 不会启动,并在日志中说明原因。

之后,Deploy 页面会将 声明部署 作为主要操作,计划与应用会到达运行时。每次应用和退役仍需等待审批。

该模块声明了四个带命名空间的实体,外加作为已应用快照的核心 Deployment:

实体 角色
definition 期望状态——期望版本对比已应用版本、spec hash、指向核心 Deployment 的链接
revision 仅追加、不可变的 spec 历史——可回滚的来源
wiring 它所声明的 agent → resource **被许可的(permitted)**连接(即模块 III 用以对照的契约)
operation 仅追加的变更管理 ledger(账本)——版本、plan hash、由谁审批、结果

期望 spec 是有类型的,并从结构体重新序列化得来(绝不经过操作员的 JSON 往返):未知字段会被拒绝, 会运行一道内联凭据守卫,任何以明文携带凭据材料的 spec 都会在声明阶段被拒绝。凭据仅以引用方式 传递(<scheme>:<locator>,scheme 在白名单内)——这是连接的一种属性,绝不是被存储的密钥。

它在事件总线上产生什么(模块 III 的“被许可”一侧)

Section titled “它在事件总线上产生什么(模块 III 的“被许可”一侧)”

模块 VII 从不写入 access map(访问地图);模块 III 是其边的唯一写入者。在一次已提交的 apply 上, 针对每条 wiring,该模块会发布一个 policy-grant 类型的 edge.observed 事件(Source = policy),其中仅携带引用与模式(mode)。 模块 III 将其协调进自身 permitted-vs-observed(被许可 vs 被观测)差异中被许可的一侧——因此本模块 所声明的内容,恰恰就是模块 III 用来对照其所观测内容的依据。身份按智能体通过治理进行绑定:一个稳固、 唯一的非人类身份会产生一条 attributed(已归因)的边;一个共享或缺失的身份则被报告为 approximate (近似)——标记出来,绝不伪造。