3. 服务目录(Service Catalog)架构:如何通过 Composition 定义服务模板,实现基础设施即代码

在 Crossplane 生态中,服务目录(Service Catalog) 并非传统意义上的 UI 市场,而是一套由 CompositeResourceDefinition(XRD) 和 Composition 构成的声明式模板体系。它让平台团队能够将底层云资源(VPC、RDS、Redis 等)封装为面向应用团队的“服务产品”,实现真正的 基础设施即代码(IaC)。

3.1 服务目录的核心组件

服务目录由三个关键层组成,每一层都对应一个 Kubernetes 自定义资源:

组件 Kubernetes 资源类型 职责
XRD CompositeResourceDefinition 定义服务产品的 API Schema(输入参数、输出状态)
Composition Composition 定义资源编排模板(如何将输入参数转化为底层资源)
Claim(XRC) CompositeResourceClaim 应用团队提交的“服务申请单”(指定参数、触发资源创建)
关键理解: XRD 是“接口定义”,Composition 是“实现逻辑”,Claim 是“调用请求”。三者分离使得平台团队可以升级 Composition 实现而不影响应用团队的 API 调用方式。

3.2 Composition 模板的结构与语法

Composition 是服务目录的核心编排引擎。它通过 resources 数组定义一组需要创建的托管资源(Managed Resources),并支持 补丁(Patches) 和 连接细节(Connection Details) 的传递。

以下是一个典型的 Composition 模板片段,用于定义一个“生产级 PostgreSQL 实例”:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xpostgresqls.aws.database.example.org
spec:
  compositeTypeRef:
    apiVersion: aws.database.example.org/v1alpha1
    kind: XPostgreSQL
  resources:
    - name: rds-instance
      base:
        apiVersion: rds.aws.upbound.io/v1beta1
        kind: Instance
        spec:
          forProvider:
            engine: postgresql
            engineVersion: "15.3"
            instanceClass: db.r5.large
            allocatedStorage: 100
            dbName: mydb
            username: admin
            passwordSecretRef:
              name: db-password
              namespace: crossplane-system
              key: password
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.storageGB
          toFieldPath: spec.forProvider.allocatedStorage
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.instanceClass
          toFieldPath: spec.forProvider.instanceClass
    - name: security-group
      base:
        apiVersion: ec2.aws.upbound.io/v1beta1
        kind: SecurityGroup
        spec:
          forProvider:
            description: "Security group for PostgreSQL"
            ingress:
              - fromPort: 5432
                toPort: 5432
                protocol: tcp
                cidrBlocks:
                  - 10.0.0.0/8
      patches:
        - type: FromCompositeFieldPath
          fromFieldPath: spec.parameters.vpcCIDR
          toFieldPath: spec.forProvider.ingress[0].cidrBlocks[0]
补丁机制: 上例中 FromCompositeFieldPath 将 XRD 实例(XPostgreSQL)的 spec.parameters.storageGB 映射到 RDS Instance 的 spec.forProvider.allocatedStorage。这使得应用团队只需在 Claim 中填写 storageGB: 200,Composition 自动完成参数注入。

3.3 服务目录的请求与交付流程

下图展示了从应用团队提交 Claim 到资源交付完成的完整链路:

服务目录请求与交付流程 应用团队 提交 Claim CompositeResourceClaim (XRC) XRD 校验 API Schema 验证 Composition 资源编排模板 RDS Instance 托管资源 SecurityGroup 托管资源 SubnetGroup 托管资源 AWS / GCP / Azure 关键路径 Claim → XRD 校验 → Composition 解析 → 创建托管资源 → 云提供商 API 调用

3.4 Composition 的高级编排模式

当服务模板需要处理复杂依赖或条件逻辑时,Composition 支持以下高级模式:

  • 资源依赖排序: 通过 dependsOn 字段显式声明资源创建顺序。例如:先创建 VPC,再创建子网,最后创建 RDS 实例。
  • 条件资源创建: 使用 patches 中的 CombineFromCompositeFieldPath 实现条件判断。例如:当 spec.parameters.environment == "production" 时,自动添加只读副本。
  • 连接细节传递: 通过 connectionDetails 将资源输出(如 RDS 端点、端口)注入到 Kubernetes Secret 中,应用团队可直接挂载使用。
  • Readiness Checks: 定义资源就绪探针,确保所有底层资源完全可用后,Claim 才标记为 Ready。
常见陷阱: 不要在 Composition 中硬编码敏感信息(如密码、密钥)。应使用 passwordSecretRef 引用外部 Secret,或通过 fromFieldPath 从 XRD 参数中动态注入。硬编码会导致安全审计失败和密钥轮换困难。

3.5 服务目录的版本管理与演进

随着业务发展,服务模板需要持续迭代。Crossplane 通过 Composition Revision 机制支持无损升级:

版本策略 实现方式 适用场景
向后兼容 新增 XRD 字段时设置 required: false,Composition 中提供默认值 添加可选功能(如新增备份配置)
版本分支 创建新的 XRD + Composition 组合(如 v2),旧版本保留 重大架构变更(如从单机迁移到集群)
滚动升级 修改 Composition 后,Crossplane 自动创建新 Revision,现有资源逐步迁移 参数调整、资源类型替换

通过 Composition 定义服务模板,平台团队能够将基础设施的复杂性隐藏在标准化的 API 背后,让应用团队以“声明式调用”的方式获取所需资源,真正实现 基础设施即代码 的承诺。