资讯详情

Crossplane OAM 工作流实战:基于 core.oam.dev 的组件化应用定义、参数注入与跨集群调度全流程解析

📅 2026/9/23 17:44:58 | 华诺云谱 👁 阅读
Crossplane OAM 工作流实战:基于 core.oam.dev 的组件化应用定义、参数注入与跨集群调度全流程解析
云原生后端【免费下载链接】crossplaneThe Cloud Native Control Plane项目地址https://gitcode.com/gh_mirrors/cr/crossplane点击查看免费下载本篇技术指南以 Crossplane 仓库中标记为 Defunct已废弃的 OAM POC 设计文档为主体完整还原一次基于 Open Application ModelOAM的应用部署链路从Component定义部署单元到ApplicationConfiguration组装应用并注入参数再到ContainerizedWorkload被控制器打包为KubernetesApplication并调度到目标 Kubernetes 集群。读者将掌握这套 POC 工作流中每个 CRD 的职责、控制器在每一环的调和行为、参数覆盖机制以及其底层KubernetesApplication架构的调度/应用/资源三控制器模型并了解该方案最终被废弃、演进的历史脉络。一、文档定位与历史背景本文所讲解的工作流出自仓库中的设计文档 one-pager-oam-workflow.md其状态为Defunct废弃由 Dan Mangumhasheddan撰写对应 Crossplane 早期 PR #1276 中的 OAM 类型实现。文档开篇明确了两点关键事实文档描述的是初始 POC概念验证阶段的控制器行为这些控制器计划在后续迭代中移出 core Crossplane不属于长期架构。文档同时提到OAM 的长期实现方案参考了独立的 OAM Runtime Architecture 设计文档。因此阅读本文时应将其视为一份历史设计快照——它记录了 Crossplane 曾经如何通过 OAM 模型承载应用定义—组装—调度的完整链路这对理解 Crossplane 应用建模思想的演进尤其是后来的 Composition 体系具有重要参考价值。从当前仓库源码结构看这一演进确实发生了在internal目录下已搜索不到任何core.oam.dev相关的控制器实现cluster/crds目录中的 CRD 清单如 apiextensions.crossplane.io_compositeresourcedefinitions.yaml、pkg.crossplane.io_providers.yaml 等也全部归属于apiextensions.crossplane.io、pkg.crossplane.io、ops.crossplane.io、protection.crossplane.io等 API 组core.oam.dev类型的 CRD 已不在安装清单中——这正是文档预告的移出 core Crossplane的最终结果。二、安装随 Crossplane 一起部署的 OAM 组件2.1 随安装落地的 OAM CRD按照文档描述安装 Crossplane 时以下 6 个 OAM CRD 会被一并安装CRD角色定位ApplicationConfiguration组装多个Component并注入参数生成工作负载实例的应用级资源Component定义一个可被ApplicationConfiguration引用的部署单元TraitDefinition定义可附加到工作负载上的运维特征如扩缩容、监控ScopeDefinition定义工作负载的适用范围/边界WorkloadDefinition将某种工作负载类型apiVersion/kind注册为 OAM 可用的 workloadContainerizedWorkload核心的容器化工作负载类型描述容器的镜像、资源、环境变量与端口2.2 自动创建的 WorkloadDefinition 实例除 CRD 之外Crossplane 安装时还会自动创建一个WorkloadDefinition实例用于将内置的ContainerizedWorkload类型注册为 OAM 可用的核心 workloadapiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata: name: containerizedworkloads.core.oam.dev spec: definitionRef: name: containerizedworkloads.core.oam.dev这个实例的存在使得ContainerizedWorkload可以被 OAMComponent引用。文档特别强调了一种可扩展模式要引入其他工作负载类型只需两件事——为该 workload 创建对应的 CRD再创建一个引用该 CRD 的WorkloadDefinition。也就是说WorkloadDefinition是 OAM 工作负载类型的注册表入口新类型接入无需改动 Crossplane 核心代码。2.3 随安装启动的 OAM 控制器安装完成后两个 OAM 相关的控制器会被启动它们构成了工作流的执行引擎Application Configuration controller监听ApplicationConfiguration资源根据其内联参数和所引用的Component创建对应的工作负载实例Containerized Workload controller监听ContainerizedWorkload资源将其打包为KubernetesApplication以便调度到目标集群。这两者的职责划分非常清晰前者完成OAM 模型 → 具体工作负载的翻译后者完成工作负载 → 可调度应用单元的打包。后续第 35 节将沿这两条链路逐一展开。三、创建 Component定义可复用的部署单元Component是用户定义部署单元的入口它描述一个应用组件需要什么样的 workload在 POC 中即ContainerizedWorkload并可通过parameters暴露可调参数供上层覆盖。3.1 完整示例apiVersion: core.oam.dev/v1alpha2 kind: Component metadata: name: myapp spec: workload: apiVersion: core.oam.dev/v1alpha2 kind: ContainerizedWorkload metadata: name: my-workload spec: osType: linux containers: - name: tbs11-app image: hasheddan/tbs11:latest resources: cpu: required: 1.0 memory: required: 100MB env: - name: DB_HOST valueFrom: secretKeyRef: name: mysqlconn key: endpoint - name: DB_USER valueFrom: secretKeyRef: name: mysqlconn key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: mysqlconn key: password ports: - containerPort: 8080 parameters: - name: imageName required: false fieldPaths: - spec.containers[0].image3.2 关键设计点workload 字段内嵌一个完整的 workload 对象。这里是ContainerizedWorkload其spec描述运行平台osType: linux、容器镜像、资源需求CPU 1.0 核、内存 100MB、环境变量与端口。环境变量使用了valueFrom.secretKeyRef从名为mysqlconn的 Secret 中读取endpoint/username/password——这体现了 Crossplane 早期托管资源连接信息以 Secret 注入应用的消费模型。parameters 机制spec.parameters声明组件对外暴露的可调参数。示例中的imageName参数通过fieldPaths: [spec.containers[0].image]将参数名映射到 workload 内部字段路径required: false表示该参数可选。这是实现同一组件在不同环境复用不同镜像的关键机制。不触发任何调和文档明确说明创建Component本身不会触发任何 Crossplane 控制器的调和动作。Component只是图纸真正触发工作负载创建的是引用它的ApplicationConfiguration。四、创建 ApplicationConfiguration组装组件并注入参数要让上述Component真正部署用户必须创建一个引用它的ApplicationConfiguration。4.1 完整示例apiVersion: core.oam.dev/v1alpha2 kind: ApplicationConfiguration metadata: name: myapp-dev spec: components: - componentName: myapp parameterValues: - name: imageName value: hello-world:latest4.2 控制器的调和行为创建ApplicationConfiguration后Application Configuration controller 会入队一次调和reconcile。调和期间控制器会为spec.components中每一个引用的Component创建工作负载实例。就本示例而言控制器将根据myapp组件的定义实例化一个ContainerizedWorkloadapiVersion: core.oam.dev/v1alpha2 kind: ContainerizedWorkload metadata: name: myapp-workload spec: osType: linux containers: - name: tbs11-app image: hello-world:latest # 由 ApplicationConfiguration controller 根据其 spec 中的参数替换 resources: cpu: required: 1.0 memory: required: 100MB env: - name: DB_HOST valueFrom: secretKeyRef: name: mysqlconn key: endpoint - name: DB_USER valueFrom: secretKeyRef: name: mysqlconn key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: mysqlconn key: password ports: - containerPort: 8080对照第 3 节的Component定义可以看到两处显著变化镜像被替换spec.containers[0].image从hasheddan/tbs11:latest变成了hello-world:latest。这正是parameterValues中imageName: hello-world:latest通过fieldPaths路径写入的结果——参数注入发生在控制器创建 workload 实例的时刻而不是Component定义时刻。实例命名变化实例名为myapp-workload对应Component中metadata.name: my-workload与上层命名规则的组合而不是Component的名字myapp。其余字段资源配额、环境变量、端口被原样继承说明ApplicationConfiguration只负责组装 覆盖未声明覆盖的部分保持Component定义不变。五、从 ContainerizedWorkload 到 KubernetesApplication打包与调度ContainerizedWorkload实例的创建会再次触发其控制器的调和。此时轮到第二个控制器——Containerized Workload controller——登场它将ContainerizedWorkload打包进一个KubernetesApplication从而进入 Crossplane 既有的调度体系。5.1 打包生成的 KubernetesApplicationapiVersion: workload.crossplane.io/v1alpha1 kind: KubernetesApplication metadata: name: myapp-workload-0003 spec: resourceSelector: matchLabels: app: 2a23de82-58e4-11ea-8e2d-0242ac130003 # 该 ContainerizedWorkload 的 UID targetSelector: matchLabels: # TODO: 是否透传调度标签 resourceTemplates: - metadata: name: myappworkload-deployment labels: app: 2a23de82-58e4-11ea-8e2d-0242ac130003 spec: template: apiVersion: apps/v1 kind: Deployment metadata: namespace: default name: myapp-workload labels: app: 2a23de82-58e4-11ea-8e2d-0242ac130003 spec: selector: matchLabels: app: 2a23de82-58e4-11ea-8e2d-0242ac130003 template: metadata: labels: app: 2a23de82-58e4-11ea-8e2d-0242ac130003 spec: - name: tbs11-app image: hello-world:latest resources: cpu: required: 1.0 memory: required: 100MB env: - name: DB_HOST valueFrom: secretKeyRef: name: mysqlconn key: endpoint - name: DB_USER valueFrom: secretKeyRef: name: mysqlconn key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: mysqlconn key: password ports: - containerPort: 8080注上述resourceTemplates[0].spec.template中的 Deployment 定义在 POC 文档中省略了containers键原文直接在spec.template.spec下列出容器条目。按 Kubernetes Deployment 对象模型实际生效的模板应在spec.template.spec.containers下声明容器此处保留原文结构便于对照原始设计文档。5.2 打包逻辑的关键语义resourceSelector 与 UID 标签resourceSelector.matchLabels使用app: ContainerizedWorkload 的 UID作为关联键。控制器用 UID 而非名称做标签是为了在跨集群场景下保持唯一性避免不同命名空间/集群中的同名资源互相干扰。targetSelector 与调度标签targetSelector.matchLabels留空并带TODO注释是否透传调度标签说明在 POC 阶段调度目标的选择尚未完整设计——这是文档自带的未决问题标记。resourceTemplates 模板化resourceTemplates将ContainerizedWorkload的容器配置翻译成一个apps/v1的Deployment模板命名空间default、Deployment 名myapp-workload容器镜像、资源配额、环境变量、端口全部继承自 workload 定义。文档最后指出从此之后KubernetesApplication将按照其既有控制器的行为被调度。换言之OAM 工作流到这一步就完成了与既有 Crossplane 工作负载体系的对接——后续的调度、远程资源创建与状态回写不再属于 OAM 专属逻辑。六、底层架构佐证KubernetesApplication 的三控制器模型本工作流中作为调度终点的KubernetesApplication其完整架构在仓库的姊妹设计文档 design-doc-complex-workloads.md 中有系统性论述该文档同样标记为 Defunct。理解这套模型才能看懂第 5 节中按既有控制器的行为被调度的具体含义。该文档提出将当时compute.crossplane.io/v1alpha1组的Workload替换为workload.crossplane.io/v1alpha1组的KubernetesApplication并将控制器拆分为三个各司其职的角色控制器职责scheduler controller监听KubernetesApplication将其调度分配到某个KubernetesClusterapplication controller监听已调度的KubernetesApplication按resourceTemplates创建/更新/删除KubernetesApplicationResource设置 controller reference维护.status.desiredResources与.status.submittedResources统计resource controller监听已调度的KubernetesApplicationResource向目标集群传播依赖 Secret、创建/更新模板化资源Deployment、Service、Job、ConfigMap 等并把远端资源的.status回写到自身.status.remote其中与本工作流直接相关的设计决策包括原子调度单元KubernetesApplication是不可跨集群拆分的调度原子其下每个KubernetesApplicationResource恰好模板化一个任意 Kubernetes 资源。工作流中的 Deployment 模板正是被KubernetesApplicationResource包裹后才下发到目标集群。Secret 传播与命名KubernetesApplicationResource通过.spec.secretscorev1.LocalObjectReference列表声明依赖的托管资源连接 Secret控制器将其传播到模板化资源所在命名空间。为避免多个模板引用同一 Secret 时的命名冲突传播后的 Secret 名由资源模板名与 Secret 名拼接而来——例如名为wordpress-deployment的资源模板引用名为mysql的 Secret传播到目标集群后将成为wordpress-deployment-mysql。命名空间的无立场约定文档明确反对在应用级别统一指定目标命名空间理由是模板可指向任意资源类型包括Namespace、CRD 等集群作用域资源统一指定会带来令人意外的行为。因此命名空间由每个资源模板的对象元数据自行决定未指定时按 Kubernetes 惯例落入default命名空间——与本工作流示例中namespace: default的行为一致。所有权与防冲突application controller 通过 controller reference 认领自己模板化的KubernetesApplicationResource避免多个应用争夺同名资源远程资源则由 resource controller 打上kubernetesapplicationresource.workload.crossplane.io/uid注解来标识归属防止两个模板竞争创建同一个远端 Deployment。状态透明用户无需连接目标集群即可通过KubernetesApplicationResource的.status.remote查看远端资源的原始状态。七、调度目标的演进从 clusterSelector 到 KubernetesTarget本工作流中KubernetesApplication的targetSelector之所以留作 TODO与同时期的集群消费模型演进直接相关。仓库中的 one-pager-consuming-k8s-clusters.md同样为 Defunct 状态记录了后续方案引入命名空间级的KubernetesTarget资源用于发布Kubernetes 集群它可以通过clusterRef引用集群作用域的 Kubernetes 集群托管资源如GKECluster或通过connectionSecretRef直接引用命名空间内的本地 kubeconfigSecret——后者天然支持Bring Your Own Cluster自带集群场景KubernetesApplication的调度从按标签选择KubernetesCluster声明改为按标签选择KubernetesTarget对应 API 字段由clusterSelector更名为targetSelector、clusterRef更名为targetRefapiVersion由v1alpha1升至v1alpha2新增一个自动创建控制器当KubernetesCluster声明变为 Bound 时自动在命名空间内创建对应KubernetesTarget带 ownerReference随声明删除而清理从而在无需用户具备创建KubernetesTarget权限的前提下保持自助服务。这解释了本工作流示例中targetSelector的 TODO 状态它处于调度目标概念正在从集群声明向发布型资源迁移的中间节点。八、为什么止步于 POC局限性与后续演进OAM 工作流最终被标记为 Defunct 并整体移出 core Crossplane除了控制器逻辑不应留在核心的组织原因外其承载层KubernetesApplication的代理模型本身也面临体验问题。仓库中的 design-doc-agent.md 对此有直白的记录失去准入校验KubernetesApplicationResource是模板编辑后需等控制器重新下发才能生效错误不再被 admission 检查在写入时拦截而是事后反映在状态里late initialization 问题远端资源如Pod的spec.node被控制器延迟补全的字段由于模板非强类型且只回写 status用户难以区分自己声明的期望与控制器补全的值对数组元素执行 PATCH 时可能整体替换破坏被补全的簿记字段存量应用迁移成本高要把一个 Helm chart 部署到与 Crossplane 不同集群需要把每个资源逐一改造成KubernetesApplicationResource模板改造量随 chart 规模线性放大。这些痛点指向了一个方向与其在中心集群推送代理资源到远端不如让应用运行在目标集群、以拉取方式消费中心集群的托管资源。这一认识深刻影响了 Crossplane 后续的 Composition 与 Provider 体系参见仓库 design/design-doc-composition.md 等设计文档也是本文所讲 POC 工作流最重要的历史价值——它完整演练了应用模型OAM—工作负载抽象ContainerizedWorkload—调度单元KubernetesApplication的三层抽象链条为后来者理解 Crossplane 应用建模的取舍提供了不可多得的对照样本。结语从Component的静态定义到ApplicationConfiguration的参数注入再到ContainerizedWorkload被打包为KubernetesApplication进入调度体系这份 OAM POC 工作流展示了 Crossplane 早期在应用建模层的一次完整实践。它虽然已经废弃但其暴露的控制器拆分、参数覆盖、UID 标签关联、Secret 传播约定等设计细节仍然是以史为鉴理解 Crossplane 架构演进的关键材料。希望本文档的完整还原能帮助读者在研究 one-pager-oam-workflow.md 及相关设计文档时快速建立从应用定义到集群调度的全局视图。赞分享云原生后端【免费下载链接】crossplaneThe Cloud Native Control Plane项目地址https://gitcode.com/gh_mirrors/cr/crossplane点击查看免费下载相关推荐定义云原生应用基于 OAM 开放应用模型的组件、特征与作用域实战指南定义云原生应用基于 OAM 开放应用模型的组件、特征与作用域实战指南 本篇技术指南以 define cloud native app.md https://l教程云原生容器编排XTuner 多轮对话 SFT 微调实战基于 multi_turn_1 示例的自定义数据集与 map_fn 全流程解析XTuner 多轮对话 SFT 微调实战基于 multi_turn_1 示例的自定义数据集与 map_fn 全流程解析 本文以 XTuner 官方示例 exa大模型模型微调MiniCPM3 Function Calling 实战基于 vLLM 与自定义 Tool Parser 的工具调用全流程指南MiniCPM3 Function Calling 实战基于 vLLM 与自定义 Tool Parser 的工具调用全流程指南 本文以 MiniCPM3 4B人工智能大模型基础模型本地部署微调模型量化openBMB上一篇规避法律风险SillyTavern用户必须了解的知识产权合规指南下一篇终极指南Cherry Studio端到端加密如何保障您的数据安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。