实体与关系 — 所有权为什么是目录的心脏
一句话总结
目录不是服务列表,而是关系图。与其背实体种类,不如理解每种实体回答什么问题。
为什么需要它
只有服务清单无法回答:删除 API 会破坏什么(依赖);团队解散由谁接手(所有权);支付领域整体状态(System/Domain);数据库属于谁(Resource)。因此 Backstage 把实体分种类并保存关系。
工作原理
| kind | 回答 | 代表字段 |
|---|---|---|
| Component | 构建和部署的软件 | spec.type、spec.lifecycle、spec.owner、spec.system |
| API | 暴露或消费的接口 | spec.type、spec.definition |
| Resource | 所需基础设施 | spec.type |
| System | 协同实体集合 | spec.owner、spec.domain |
| Domain | 跨系统业务领域 | spec.owner |
| Group | 团队、组织 | spec.type、spec.children、spec.profile |
| User | 人 | spec.memberOf |
| Location | 指向其他实体的位置 | spec.type、spec.targets |
另有 Scaffolder 的 Template。spec.lifecycle 是自由字符串,惯例为 experimental / production / deprecated,可筛选待废弃服务。
relation 是计算结果
catalog-info.yaml 声明 spec.owner、spec.system、spec.providesApis 等,目录据此计算双向关系:
spec.owner: group:team-checkout → ownedBy / ownerOf
spec.system: commerce → partOf / hasPart
spec.providesApis: [checkout-api] → providesApi / apiProvidedBy
spec.consumesApis: [payments-api] → consumesApi / apiConsumedBy
spec.dependsOn: [resource:checkout-db] → dependsOn / dependencyOf
所以只在一侧写 providesApis,API 页面也会显示提供者,无需手写反向关系。
实体引用格式
[<kind>:][<namespace>/]<name>
kind、namespace 可省略,namespace 默认为 default。
| 写法 | 解释 |
|---|---|
team-checkout |
上下文默认 kind + default |
group:team-checkout |
group:default/team-checkout |
group:payments/team-checkout |
显式 namespace |
spec.owner 等字段有默认 kind,但像 team-checkout 这样的值显式写成 group: 更利于评审,能立即看出是团队而非个人。
为什么 catalog-info.yaml 与代码同库
填充目录有三种方式:设置文件中的静态 URL(仅适合小规模);Location 实体指向其他文件;discovery 扫描组织仓库并自动发现 catalog-info.yaml(实践首选)。第三种要求文件与代码同库,使创建者填写 owner、变更走 PR、归档仓库时实体一并消失、结构变化能同提交更新。集中到一个中央仓库则无人有动力更新,最易腐烂。
所有权为何是核心
所有者决定事故通知、漏洞工单、成本归属和废弃决策。应避免指向个人 User,而要指向团队 Group:个人会离职,团队会承接。错误所有权是目录崩坏的首要原因。
现场表现
Kubernetes 的 app.kubernetes.io/name、app.kubernetes.io/part-of 等标准标签与目录思想相同。Helm 还常用 app.kubernetes.io/name、instance、version、component、part-of、managed-by。
app.kubernetes.io/name→ Component 名称app.kubernetes.io/part-of→ Systemapp.kubernetes.io/component→ 类似 Component 的spec.type
应在集群标签与目录实体中一致表达所有权、归属。Backstage Kubernetes 插件通过实体 annotation backstage.io/kubernetes-id,查找集群中同值标签的 workload 并展示。gpu.homelab/tier=xlarge 这类语义标签也在把物理事实翻译成人可用于决策的词汇。
下一步
将在 /root/cba-catalog/ 编写 Component、API、Resource、System、Domain、Group、User、Location,随后以真实集群标签表达同一所有权,用 kubectl 验证,并输出规范化实体引用。