核心概念
- ResourceGraphDefinition (RGD) 的 schema 部分定义了自定义 API 的形状
- 创建一个 RGD 时,kro 会基于这个 schema 生成一个 CRD,用户就可以实例化这个 CRD
核心功能
API 身份标识
生成的 CRD API 将是 mycompany.io/v1alpha1,资源名为 applications.mycompany.io
1 2 3 4
| schema: apiVersion: v1alpha1 kind: Application group: mycompany.io
|
作用域
| 值 |
描述 |
| Namespaced |
实例存在于 namespace 内(默认) |
| Cluster |
实例是集群级别的 |
- 使用 scope: Cluster 时,所有 namespaced 资源必须显式设置 metadata.namespace
- 否则 kro 会在 RGD 创建时验证失败
Spec 字段(用户输入)
使用 SimpleSchema 语法定义用户可配置的字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| spec: name: string | required=true replicas: integer | default=3 minimum=1 maximum=100 enabled: boolean | default=false
ingress: enabled: boolean | default=false host: string
env: "map[string]string" ports: "[]integer"
|
常用验证标记
- required=true - 必填字段
- default=value - 默认值
- minimum/maximum - 数值约束
- enum=”val1,val2” - 枚举值
- pattern=”regex” - 正则验证
Status 字段(运行时状态)
使用 CEL 表达式从被管理资源中提取状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| status: availableReplicas: ${deployment.status.availableReplicas}
serviceIP: ${service.spec.clusterIP}
endpoint: "http://${service.status.loadBalancer.ingress[0].hostname}"
isHealthy: ${deployment.status.availableReplicas >= deployment.spec.replicas}
readyPods: ${deployment.status.conditions.filter(c, c.type == "Ready")}
|
kro 自动处理的字段
conditions 和 state 不可覆盖
1 2 3 4
| status: conditions: [...] state: ACTIVE
|
完整工作流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ RGD Schema │───▶│ CRD 生成 │───▶│ 用户创建实例 │ │ SimpleSchema │ │ OpenAPI v3 │ │ kubectl apply │ └─────────────────┘ └──────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ Kubernetes 验证 │ │ 类型检查/必填 │ └─────────────────┘ │ ▼ ┌─────────────────┐ │ kro 处理 │ │ CEL 表达式求值 │ │ 状态持续更新 │ └─────────────────┘
|
高级特性
自定义类型
1 2 3 4 5 6 7 8 9 10
| schema: types: ContainerConfig: image: string | required=true tag: string | default="latest" env: "map[string]string"
spec: primary: ContainerConfig sidecars: "[]ContainerConfig"
|
递归类型
kro 会自动解析依赖并检测循环引用
1 2 3 4 5 6 7 8
| schema: types: Address: street: string city: string Person: name: string address: Address
|
Additional Printer Columns
控制 kubectl get 的输出列
1 2 3 4 5 6 7 8
| schema: additionalPrinterColumns: - name: Replicas type: integer jsonPath: .spec.replicas - name: Available type: integer jsonPath: .status.availableReplicas
|
1 2 3
| 输出效果: NAME REPLICAS AVAILABLE AGE my-app 5 5 10m
|
CRD 元数据
标签和注释会应用到 CRD 本身,而不是实例
1 2 3 4 5 6 7
| schema: metadata: labels: team: platform managed-by: kro annotations: description: "Application resource for managing web applications"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| graph TB subgraph "User Creates" RGD["ResourceGraphDefinition (RGD)<br/>apiVersion: kro.run/v1alpha1"] end
RGD -->|"contains"| SCHEMA["schema:<br/>- apiVersion, kind<br/>- spec, status<br/>- metadata"]
SCHEMA -->|"generates"| CRD["CustomResourceDefinition (CRD)<br/>Generated by kro"]
SCHEMA_METADATA["schema.metadata<br/>{labels, annotations}"] -->|"applies to"| CRD
CRD -->|"defines schema for"| INSTANCE["Custom Resource Instances<br/>{Application, WebApp, etc.}"]
INSTANCE_METADATA["instance.metadata<br/>{name, namespace, labels}"] -->|"applies to"| INSTANCE
style RGD fill:#e1f5fe style SCHEMA fill:#fff3e0 style SCHEMA_METADATA fill:#ffe0b2 style CRD fill:#c8e6c9 style INSTANCE fill:#f3e5f5 style INSTANCE_METADATA fill:#e1bee7
classDef dotted stroke-dasharray: 5 5 class SCHEMA_METADATA,INSTANCE_METADATA dotted
|
| 位置 |
应用目标 |
示例 |
| schema.metadata |
CRD 本身 |
team: platform, managed-by: kro |
| 实例的 metadata |
具体实例 |
name: my-app, namespace: prod |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| graph LR subgraph "CRD Level" CRD_OBJ["CustomResourceDefinition<br/>{kind: Application}"] CRD_LABELS["labels:<br/>team: platform<br/>managed-by: kro"] end
subgraph "Instance Level" APP1["app-one<br/>{name: app-one}"] APP2["app-two<br/>{name: app-two}"] end
CRD_OBJ -. "owns" .- APP1 CRD_OBJ -. "owns" .- APP2 CRD_LABELS --> CRD_OBJ
style CRD_OBJ fill:#c8e6c9 style CRD_LABELS fill:#a5d6a7 style APP1 fill:#f3e5f5 style APP2 fill:#f3e5f5
|
更新与兼容性
更新 RGD 的 schema 时,kro 会检查变更是否与现有实例兼容,破坏性变更(默认被阻止)
- 删除字段
- 修改字段类型
- 添加必填字段但无默认值
需要通过 Breaking Changes 机制显式允许这些变更