KRO 是 Kubernetes SIG Cloud Provider 下的子项目,旨在简化 Kubernetes 中复杂自定义资源的创建和管理
核心概念
KRO 的核心自定义资源是 ResourceGraphDefinition - RGD,它允许你:
将多个 Kubernetes 资源组合成一个可复用的组件
定义资源之间的依赖关系
为这些资源提供默认配置
工作原理
flowchart TB
subgraph User["用户层"]
A["📝 ResourceGraphDefinition<br/>(RGD)"]
B["创建资源实例"]
end
subgraph KRO["KRO 控制层"]
C["🔄 KRO Controller"]
D["🔍 分析依赖关系"]
E["📋 确定创建顺序"]
F["⚙️ 动态资源管理"]
end
subgraph K8s["Kubernetes 集群"]
G["Deployment"]
H["Service"]
I["ConfigMap"]
J["Secret"]
K["其他资源..."]
end
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
F --> H
F --> I
F --> J
F --> K
style A fill:#e1f5fe
style C fill:#fff3e0
style G fill:#e8f5e9
style H fill:#e8f5e9
style I fill:#e8f5e9
style J fill:#e8f5e9
style K fill:#e8f5e9
flowchart TB
subgraph Row1[" "]
direction LR
S1["步骤 1: 定义<br/>ResourceGraphDefinition<br/>定义资源列表和关系"]
S2["步骤 2: 应用<br/>kubectl apply<br/>应用到 kro 集群"]
S1 --> S2
end
subgraph Row2[" "]
direction LR
S3["步骤 3: 验证与创建<br/>kro 验证规范<br/>动态生成 CRD<br/>注册到 API Server"]
S4["步骤 4: 转换与管理<br/>创建 CRD 实例<br/>转换为 K8s 原生资源<br/>持续管理生命周期"]
S3 --> S4
end
Row1 --> Row2
style S1 fill:#e3f2fd
style S2 fill:#fff3e0
style S3 fill:#f3e5f5
style S4 fill:#e8f5e9
KRO 如何工作?
核心机制
flowchart TB
subgraph Step1["步骤 1: 应用 RGD"]
A["用户应用 ResourceGraphDefinition"]
end
subgraph Step2["步骤 2: 验证与创建"]
B["kro controller 验证规范"]
C["动态创建新 CRD"]
D["向 API Server 注册 CRD"]
end
subgraph Step3["步骤 3: 部署控制器"]
E["部署专用微控制器"]
F["响应 CRD 实例事件"]
end
subgraph Step4["步骤 4: 管理资源"]
G["管理每个实例的生命周期"]
H["创建/更新/删除底层资源"]
end
A --> B --> C --> D
D --> E --> F --> G --> H
style A fill:#e3f2fd
style E fill:#fff3e0
style G fill:#e8f5e9
关键设计
特性
说明
原生 K8s 原语
使用 K8s 核心能力,无额外依赖
动态 CRD 生成
自动为每个 RGD 创建对应的 CRD
微控制器架构
每个 RGD 有专用的控制器管理实例
如何使用 KRO?
基本步骤
1
定义 → 应用 → 创建实例 → 自动管理
示例场景
简单场景:WebApp
flowchart LR
subgraph RGD["ResourceGraphDefinition: WebApp"]
A["Deployment<br/>(后端服务器)"]
B["Service<br/>(特定端口)"]
end
subgraph Instance["创建实例: my-webapp"]
C["WebAppCRD 实例"]
end
subgraph Result["kro 自动创建"]
D["Deployment 资源"]
E["Service 资源"]
end
RGD --> Instance --> Result
style A fill:#e3f2fd
style B fill:#e3f2fd
style C fill:#fff3e0
style D fill:#e8f5e9
style E fill:#e8f5e9
复杂场景:WebAppWithDB (组合现有 RGD)
flowchart TB
subgraph Existing["已有 RGD"]
A["WebApp RGD"]
end
subgraph New["新 RGD: WebAppWithDB"]
B["复用 WebApp RGD"]
C["添加 Table 自定义资源 云托管数据库"]
end
subgraph Final["最终资源"]
D["Deployment"]
E["Service"]
F["数据库实例"]
end
A -.引用.-> B
B --> C
C --> D
C --> E
C --> F
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#ffe082
style F fill:#c8e6c9
使用流程总结
步骤
操作
KRO 自动处理
1
编写 ResourceGraphDefinition YAML
-
2
kubectl apply RGD 到集群
创建 CRD
3
部署微控制器
部署控制器
4
创建 CRD 实例
管理所有底层资源
为什么构建这个项目?
问题背景
痛点
说明
KRO 解决方案
多资源协同
需要同时管理多个相关资源
统一资源组,一次性管理
依赖复杂
资源间依赖关系难以维护
自动解析依赖,智能编排
编排困难
规模扩大后手动管理复杂
微控制器自动管理生命周期
配置繁琐
重复配置相似资源组合
可复用的 ResourceGraphDefinition
设计目标
目标
说明
简化构建
降低 K8s 上层应用开发的复杂度
依赖管理
自动处理资源间的依赖关系
可扩展性
支持简单和复杂的自定义资源
标准化
提供统一、可复用的资源组合方式
API 变更说明
当前状态
1 2 3
API 版本: v1alpha1 状态: 早期开发阶段 稳定性: 可能有破坏性变更
承诺与保障
flowchart LR
subgraph Evolution["API 演进"]
A["v1alpha1<br/>(当前)"]
B["v1alpha2<br/?(可能)"]
C["v1beta1<br/?(未来)"]
D["v1<br/?(稳定)"]
end
subgraph Support["支持保障"]
E["清晰的迁移路径"]
F["弃用通知"]
G["全面支持"]
end
Evolution --> Support
style A fill:#ffcc80
style D fill:#81c784
style E fill:#64b5f6
style F fill:#64b5f6
style G fill:#64b5f6
使用建议
注意事项
说明
跟进更新
关注版本发布和变更日志
测试迁移
在升级前测试新的 API 版本
社区反馈
参与项目讨论,影响 API 设计
总结
方面
核心要点
定位
简化复杂 K8s 资源编排的 Operator
机制
动态 CRD 生成 + 微控制器管理
价值
统一资源组合 + 自动依赖解析
现状
v1alpha1,积极开发中
适用
需要管理多资源组合的应用开发者
What is kro?
KRO 是什么?
KRO 的本质
1
将一组 Kubernetes 资源 → 可复用的 API
三步定义流程
步骤
操作
说明
①
定义 API Schema
描述用户接口(输入参数)
②
YAML 描述资源
定义底层 Kubernetes 资源
③
CEL 表达式连接
用 CEL 将参数绑定到资源
KRO 自动完成的工作 - Schema + Resources + CEL
flowchart LR
A["用户定义<br/>Schema + Resources + CEL"]
B["KRO 生成 CRD"]
C["监听实例创建"]
D["调和底层资源"]
A --> B --> C --> D
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#f3e5f5
style D fill:#e8f5e9
# Resource Templates 部分 resources: -deployment: spec: replicas:"${spec.replicas}"# CEL 引用 template: spec: containers: -image:"${spec.image}"# CEL 引用 ports: -containerPort:"${spec.port}"# CEL 引用
kro 的处理流程
flowchart LR
A["RGD 定义<br/>Schema + Templates"]
B["解析 CEL 表达式"]
C["推断依赖图"]
D["生成 CRD"]
E["启动 Controller"]
F["运行时处理"]
A --> B --> C --> D --> E --> F
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#ffe082
style D fill:#f3e5f5
style E fill:#e1bee7
style F fill:#c8e6c9
flowchart TB
A["spec.config<br/>(用户输入)"]
B["ConfigMap"]
C["Deployment"]
D["Service"]
A --> B
B --> C
C --> D
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#f3e5f5
style D fill:#c8e6c9
flowchart LR
User["👤 用户"]
Spec["spec (输入)<br/>image<br/>bucketName"]
KRO["⚙️ kro"]
Status["status (输出)<br/>bucketArn"]
User -->|"填写"| Spec
Spec -->|"提交"| KRO
KRO -->|"回写"| Status
Status -->|"读取"| User
style User fill:#e3f2fd
style Spec fill:#fff3e0
style KRO fill:#ffe082
style Status fill:#c8e6c9
flowchart TB
subgraph Input["用户输入"]
S["spec.image<br/>spec.bucketName<br/>metadata.name"]
end
subgraph Resources["kro 创建的资源"]
C["ConfigMap<br/>id: config"]
B["Bucket<br/>id: bucket"]
D["Deployment<br/>id: deployment"]
Svc["Service<br/>id: service"]
end
subgraph Output["状态输出"]
O["status.bucketArn"]
end
S --> C
S --> B
C --> D
B -->|"等待 status.arn"| D
D --> Svc
B --> O
style Input fill:#e3f2fd
style Resources fill:#fff3e0
style Output fill:#c8e6c9
创建顺序与时序
sequenceDiagram
participant U as 用户
participant K as kro
participant CM as ConfigMap
participant B as Bucket
participant D as Deployment
participant S as Service
U->>K: 创建 WebApp
K->>CM: 创建 ConfigMap
K->>B: 创建 Bucket
Note over K,B: 等待 bucket.status.arn 就绪
B-->>K: bucketArn 可用
K->>D: 创建 Deployment (使用 bucketArn)
K->>S: 创建 Service (引用 Deployment)
K-->>U: status.bucketArn 回写
flowchart LR
A["Simple Schema"] --> B["类型"]
A --> C["默认值"]
A --> D["约束"]
A --> E["验证"]
B --> F["一行定义"]
C --> F
D --> F
E --> F
style A fill:#e3f2fd
style F fill:#c8e6c9
flowchart TB
A["storageType = premium"]
B["standardStorage<br/>if: type == 'standard'<br/>⏭️ 跳过"]
C["dependsOnStandard<br/>⏭️ 级联跳过"]
D["premiumStorage<br/>if: type == 'premium'<br/>✅ 创建"]
E["dependsOnPremium<br/>✅ 创建"]
A --> B
B -.依赖.-> C
A --> D
D --> E
style B fill:#ffcdd2
style C fill:#ffcdd2
style D fill:#c8e6c9
style E fill:#c8e6c9
flowchart LR
subgraph CEL["CEL 表达式"]
A["确定性行为"]
B["必然终止"]
C["类型安全"]
end
subgraph Result["结果"]
D["可预测"]
E["可审计"]
F["生产安全"]
end
CEL --> Result
style CEL fill:#e3f2fd
style Result fill:#c8e6c9
特性对比总结
特性
传统 Controller
KRO
Schema 定义
OpenAPI 冗长
Simple Schema 一行
异步状态
手写重试逻辑
自动等待
依赖顺序
手动声明
CEL 自动推断
条件资源
if/else 代码块
if 表达式
批量创建
for 循环代码
forEach
安全性
图灵完备,有风险
CEL 非图灵完备
类型检查
运行时
应用时
flowchart TB
subgraph Traditional["传统 Operator 开发"]
T1["~500+ 行 Go 代码"]
T2["手动处理所有逻辑"]
T3["需要测试各种边界情况"]
end
subgraph KRO_Approach["KRO 方式"]
K1["~50 行 YAML"]
K2["kro 自动处理"]
K3["内置安全保证"]
end
subgraph Value["价值"]
V1["开发效率 10x 提升"]
V2["更少的 bug"]
V3["更快的迭代"]
end
Traditional -->|"替代"| KRO_Approach --> Value
style Traditional fill:#ffcdd2
style KRO_Approach fill:#c8e6c9
style Value fill:#e1f5fe
flowchart TB
A["用户创建 RGD"] --> B["构建 DAG 依赖图"]
B --> C["验证资源定义"]
C --> D["确定部署顺序"]
D --> E["创建 CRD"]
E --> F["监听并服务实例"]
style A fill:#e3f2fd
style B fill:#fff3e0
style C fill:#fff3e0
style D fill:#fff3e0
style E fill:#f3e5f5
style F fill:#c8e6c9
flowchart TB
subgraph Input["用户输入"]
S["schema.spec.name<br/>schema.spec.image<br/>schema.spec.replicas<br/>schema.spec.ingress.enabled"]
end
subgraph Resources["kro 创建的资源"]
D["Deployment<br/>id: deployment"]
Svc["Service<br/>id: service"]
I["Ingress<br/>id: ingress<br/>条件: ingress.enabled=true"]
end
subgraph Output["状态输出"]
O["status.deploymentConditions<br/>status.availableReplicas"]
end
S --> D
D -->|"selector"| Svc
Svc --> I
D --> O
style Input fill:#e3f2fd
style Resources fill:#fff3e0
style Output fill:#c8e6c9
依赖链
flowchart TB
subgraph Input["用户输入"]
N1["name"]
N2["image"]
N3["replicas"]
N4["ingress.enabled"]
end
D["Deployment (必选)"]
S["Service (必选)"]
I["Ingress (可选)"]
N1 --> D
N2 --> D
N3 --> D
D --> S
S --> I
N4 -.条件.-> I
style Input fill:#e3f2fd
style D fill:#fff3e0
style S fill:#f3e5f5
style I fill:#ffe082
apiVersion:kro.run/v1alpha1 kind:ResourceGraphDefinition metadata: name:my-application spec: # kro uses this simple schema to create your CRD schema and apply it # The schema defines what users can provide when they instantiate the RGD (create an instance). schema: apiVersion:v1alpha1 kind:Application spec: # Spec fields that users can provide. name:string image:string|default="nginx" replicas:integer|default=3 ingress: enabled:boolean|default=false status: # Fields the controller will inject into instances status. deploymentConditions:${deployment.status.conditions} availableReplicas:${deployment.status.availableReplicas}
# Define the resources this API will manage. resources: -id:deployment template: apiVersion:apps/v1 kind:Deployment metadata: name:${schema.spec.name}# Use the name provided by user spec: replicas:${schema.spec.replicas}# Use the replicas provided by user selector: matchLabels: app:${schema.spec.name} template: metadata: labels: app:${schema.spec.name} spec: containers: -name:${schema.spec.name} image:${schema.spec.image}# Use the image provided by user ports: -containerPort:80
-id:service template: apiVersion:v1 kind:Service metadata: name:${schema.spec.name}-svc spec: selector:${deployment.spec.selector.matchLabels}# Use the deployment selector ports: -protocol:TCP port:80 targetPort:80
-id:ingress includeWhen: -${schema.spec.ingress.enabled}# Only include if the user wants to create an Ingress template: apiVersion:networking.k8s.io/v1 kind:Ingress metadata: name:${schema.spec.name}-ingress annotations: kubernetes.io/ingress.class:alb alb.ingress.kubernetes.io/scheme:internet-facing alb.ingress.kubernetes.io/target-type:ip alb.ingress.kubernetes.io/healthcheck-path:/health alb.ingress.kubernetes.io/listen-ports:'[{"HTTP": 80}]' alb.ingress.kubernetes.io/target-group-attributes:stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60 spec: rules: -http: paths: -path:"/" pathType:Prefix backend: service: name:${service.metadata.name}# Use the service name port: number:80
部署流程
1 2 3 4 5 6 7 8 9 10 11
步骤 1: 创建 RGD 文件
# 保存为 resourcegraphdefinition.yaml
步骤 2: 应用 RGD
kubectl apply -f resourcegraphdefinition.yaml
步骤 3: 检查 RGD 状态
kubectl get rgd my-application -owide
输出解读
1 2 3
$ k get rgd my-application -owide NAME APIVERSION KIND STATE READY TOPOLOGICALORDER AGE my-application v1alpha1 Application Active True ["deployment","service","ingress"] 14s
字段
说明
STATE
Active = 已就绪可用
READY
True = 准备接受实例
TOPOLOGICALORDER
资源创建顺序
1 2 3 4
$ k get crd | grep kro applications.kro.run 2026-04-28T12:58:19Z graphrevisions.internal.kro.run 2026-04-28T12:24:15Z resourcegraphdefinitions.kro.run 2026-04-28T12:24:15Z
SandBoxPool
1 2 3
$ k get rgd -A -owide NAME APIVERSION KIND STATE READY TOPOLOGICALORDER AGE sandbox-pool v1alpha1 SandboxPool Active True ["sandboxset","trafficpolicy"] 2d21h
$ k apply -f instance.yaml application.kro.run/my-app-instance created
检查实例状态
1 2 3
$ k get applications NAME STATE READY AGE my-app-instance ACTIVE True 76s
自动创建的资源
1 2 3 4 5 6 7 8 9 10
$ k get deployments,services,ingresses NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-app 1/1 1 1 2m40s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 192.168.194.129 <none> 443/TCP 25d service/my-app-svc ClusterIP 192.168.194.157 <none> 80/TCP 2m40s
NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/my-app-ingress <none> * 80 2m40s
创建结果
资源类型
名称
说明
Deployment
my-app
1 个副本
Service
my-app-svc
ClusterIP, 80端口
Ingress
my-app-ingress
AWS ALB 类型
flowchart TB
I["Application 实例"] --> D["Deployment<br/>my-app<br/>replicas: 1"]
D --> S["Service<br/>my-app-svc<br/>ClusterIP: 80"]
S --> Ing["Ingress<br/>my-app-ingress<br/>AWS ALB"]
style I fill:#e3f2fd
style D fill:#fff3e0
style S fill:#f3e5f5
style Ing fill:#c8e6c9
实验:kro 的自动调和
实验 1: 修改副本数
1 2 3
# 编辑 instance.yaml spec: replicas:3# 从 1 改为 3
1 2 3 4 5 6
$ k edit applications my-app-instance application.kro.run/my-app-instance edited
$ k get deployment my-app NAME READY UP-TO-DATE AVAILABLE AGE my-app 3/3 3 3 6m37s
实验 2: 删除自动恢复
1 2 3 4 5
# 手动删除 Service kubectl delete service my-app-svc
# 监控自动重建 kubectl get service my-app-svc -w
sequenceDiagram
participant U as 用户
participant K as kro
participant S as Service
U->>S: kubectl delete service
S-->>K: 删除事件
Note over K: 检测到偏差
K->>S: 自动重建 Service
K-->>U: 恢复完成