
云原生DevOps运维微服务【免费下载链接】kubevelaThe Modern Application Platform.项目地址https://gitcode.com/gh_mirrors/ku/kubevela点击查看免费下载本文以 KubeVela 仓库 docs/examples/custom-trait 中的教学示例为主线讲解如何用 CUE 语言从零定义自定义组件ComponentDefinition与自定义运维特征TraitDefinition并通过vela def apply、vela def vet与vela dry-run完成从定义、校验到渲染验证的全流程。读完本文你将掌握 X-Definition 的 CUE 模板结构、output/outputs/patch的编排语义以及如何将自定义定义直接用于 Application 的组件与 trait 声明。说明KubeVela 开箱即用地内置了完整的StatefulSet组件和Storage运维特征本示例仅用于教学帮助理解自定义定义背后的原理与写法。更多定义相关设计可参考 design/vela-cli/def.md。示例目标一个有状态应用 存储卷注入整个示例只包含三个文件构成一条完整的定义—校验—渲染链路文件作用stateful.cue定义一个名为test-stateful的组件渲染 StatefulSet 工作负载volume-trait.cue定义一个名为storageclass的 trait向 Pod 注入 PVC 卷声明与挂载点app.yaml声明一个websiteApplication组合使用上述组件与 trait示例的最终效果是用户只需在 Application 中声明type: test-stateful并附带image、replicas参数再叠加type: storageclass的volumeClaimTemplates配置KubeVela 就会自动生成一个带 PVC 卷声明模板、无头 Service 的 StatefulSet。前置准备动手前需要满足以下条件已安装velaCLI并已配置可访问的 Kubernetes 集群vela def apply会把定义下发到集群对 CUEConfigure Unify Execute语法有基本了解——定义文件本质上是一段 CUE 模板了解 KubeVela 的 X-Definition 概念组件Component、运维特征Trait、策略Policy、工作流步骤Workflow Step等统称为 X-Definition在源码 pkg/definition/definition.go 中可以看到component、trait、policy、workflow-step、source、workload这六种定义类型到 K8s CRD Kind 的映射关系。第一步定义自定义 StatefulSet 组件在 stateful.cue 中定义被拆成两部分外层是定义元数据头部test-stateful: {...}内层是templateCUE 渲染模板。定义元数据test-stateful: { annotations: {} attributes: workload: definition: { apiVersion: apps/v1 kind: StatefulSet } description: StatefulSet component. labels: {} type: component }关键字段说明type: component声明这是一个组件定义ComponentDefinitionattributes.workload.definition声明该组件渲染出的工作负载是apps/v1的StatefulSetKubeVela 会据此打上workload.oam.dev/type等标签并做资源归类description供vela ls、vela show等命令展示的可读描述。渲染模板output 与 outputstemplate: { output: { apiVersion: apps/v1 kind: StatefulSet metadata: name: context.name spec: { selector: matchLabels: app: context.name minReadySeconds: 10 replicas: parameter.replicas serviceName: context.name template: { metadata: labels: app: context.name spec: { containers: [{ name: nginx ports: [{ name: web containerPort: 80 }] image: parameter.image }] terminationGracePeriodSeconds: 10 } } } } outputs: web: { apiVersion: v1 kind: Service metadata: { name: context.name labels: app: context.name } spec: { clusterIP: None ports: [{ name: web port: 80 }] selector: app: context.name } } parameter: { image: string replicas: int } }这里体现了 KubeVela CUE 模板的两大编排原语output组件渲染出的主资源这里是有状态工作负载 StatefulSet。metadata.name、serviceName、selector、template.labels均通过context.name引用——context是 KubeVela 注入的上下文对象context.name即组件名本示例中为custom-component保证资源命名与组件名一致。outputs附加资源。outputs: web额外渲染了一个clusterIP: None的无头 ServiceHeadless Service这是 StatefulSet 稳定网络标识DNS 域名所必需的配套资源。parameter声明该组件对外暴露的参数及类型约束。image: string与replicas: int将直接映射为 Application 中properties的字段若用户传错类型如把replicas传成字符串渲染时会直接报错——参数校验由 CUE 的类型系统天然完成。应用定义$ vela def apply stateful.cue ComponentDefinition test-stateful created in namespace vela-system.vela def apply会把 CUE 定义转换为对应的 ComponentDefinition CRD 对象并下发到集群。从源码 references/cli/def.go 可以看到该命令支持.cue、.yaml与 Godefkit三种定义文件默认下发到vela-system命名空间可用-n/--namespace指定也支持传目录批量下发还提供--dry-run标志只构建 CRD 对象而不真正下发# 指定命名空间 vela def apply ./defs/my-trait.cue --namespace default # 只构建不应用 vela def apply ./defs/my-trait.cue --dry-run第二步定义自定义存储卷 Traitvolume-trait.cue 定义了一个名为storageclass的运维特征作用是给遵循spec.templatePod 结构的负载注入存储卷声明与挂载。定义元数据storageclass: { type: trait annotations: {} labels: {} description: Add storageclass on K8s pod for your workload which follows the pod spec in path spec.template. attributes: { appliesToWorkloads: [*] } }与组件定义不同trait 的type: trait声明其是一个 TraitDefinitionattributes.appliesToWorkloads: [*]表示该 trait 可以作用于任意类型的工作负载也可是具体的负载类型列表。同时注意其 description 中的约束该 trait 通过 CUE patch 修改的是负载spec.template路径下的 Pod 结构因此只适用于遵循这一 Pod 布局的工作负载StatefulSet、Deployment 等均满足。模板列表推导与 patchtemplate: { volumeClaimTemplatesList: *[ for v in parameter.volumeClaimTemplates { { metadata: name: v.name spec: { accessModes: [ReadWriteOnce] resources: requests: storage: v.requests storageClassName: v.storageClassName } } }, ] | [] volumeClaimTemplateVolumeMountsList: *[ for v in parameter.volumeClaimTemplates { { name: v.name mountPath: v.mountPath } }, ] | [] patch: { // patchKeyname spec: { template: spec: { containers: [...{ // patchKeyname volumeMounts: volumeClaimTemplateVolumeMountsList }] } // patchKeyname volumeClaimTemplates: volumeClaimTemplatesList } } parameter: { volumeClaimTemplates?: [...{ name: string requests: string storageClassName: string mountPath: string }] } }这是理解自定义 trait 的核心拆解如下列表推导comprehensionfor v in parameter.volumeClaimTemplates遍历用户在 Application 中传入的卷声明列表分别生成两份派生数据volumeClaimTemplatesList完整的volumeClaimTemplates声明含accessModes: [ReadWriteOnce]、存储容量requests.storage、storageClassNamevolumeClaimTemplateVolumeMountsList对应的挂载点列表namemountPath。写法*[...] | []表示默认值为空列表星号标记默认值竖线后是可选分支当用户未传volumeClaimTemplates时模板仍能合法求值。patch 语义与组件定义用output全量生成资源不同trait 用patch在既有工作负载上做增量修改。这里 patch 了spec.template.spec.containers[].volumeMounts与spec.volumeClaimTemplates两个路径。// patchKeyname注释这是 KubeVela 对 CUE patch 的关键扩展——声明合并策略。patchKeyname表示按name字段作为键进行列表合并而非整体替换同名的卷声明/挂载会被合并或覆盖不同名的新增项会被追加避免与工作负载模板中已有的挂载冲突。该 trait 正是借此在 StatefulSet 上追加volumeClaimTemplates并让容器挂载对应卷。参数定义parameter.volumeClaimTemplates?是可选参数数组每个元素包含name、requests、storageClassName、mountPath四个必填字符串字段。应用定义$ vela def apply volume-trait.cue TraitDefinition storageclass created in namespace vela-system.第三步校验定义vela def vet在把定义应用于真实应用前可以先本地校验 CUE 文件语法与定义结构$ vela def vet volume-trait.cue Validation succeed.vela def vet的实现位于 references/cli/def.go它会将 CUE 文件解析为 Definition 对象pkgdef.Definition{...}.FromCUEString若 CUE 语法或定义字段不合法则返回错误校验通过则输出Validation file succeed.。该命令同时支持.go定义文件也支持一次校验多个文件或整个目录vela def vet my-def1.cue my-def2.go my-def3.cue vela def vet ./test1/ ./test2/第四步编写 Application 并 Dry-Run 验证Application 清单app.yaml 声明了一个website应用将前面定义的两个自定义定义组合使用apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: website namespace: default spec: components: - name: custom-component type: test-stateful properties: image: nginx:latest replicas: 1 traits: - type: storageclass properties: volumeClaimTemplates: - name: test requests: 1Gi storageClassName: local-path mountPath: /usr/share/nginx/html结构要点type: test-stateful对应第一步定义的组件properties.image、properties.replicas精确匹配其parameter声明traits[].type: storageclass对应第二步定义的 traitproperties.volumeClaimTemplates传入卷声明列表其中name: test、requests: 1Gi、storageClassName: local-path、mountPath: /usr/share/nginx/html将分别进入 patch 后的卷声明模板与容器挂载。Dry-Run 渲染在真实部署前用 dry-run 在本地渲染出最终 K8s 资源验证自定义定义的编排结果vela dry-run -f app.yaml渲染结果包含两个资源为便于阅读以下为原文档给出的输出结构实际渲染出的字段值随app.yaml中的properties而定# Application(website) -- Component(custom-component) --- apiVersion: apps/v1 kind: StatefulSet metadata: annotations: {} labels: app.oam.dev/appRevision: app.oam.dev/component: custom-component app.oam.dev/name: website app.oam.dev/namespace: default app.oam.dev/resourceType: WORKLOAD workload.oam.dev/type: test-stateful name: custom-component namespace: default spec: minReadySeconds: 10 replicas: 1 selector: matchLabels: app: custom-component serviceName: custom-component template: metadata: labels: app: custom-component spec: containers: - image: nginx:latest name: nginx ports: - containerPort: 80 name: web volumeMounts: - mountPath: /usr/share/nginx/html name: test terminationGracePeriodSeconds: 10 volumeClaimTemplates: - metadata: name: test spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: cbs --- apiVersion: v1 kind: Service metadata: annotations: {} labels: app: custom-component app.oam.dev/appRevision: app.oam.dev/component: custom-component app.oam.dev/name: website app.oam.dev/namespace: default app.oam.dev/resourceType: TRAIT trait.oam.dev/resource: web trait.oam.dev/type: AuxiliaryWorkload name: custom-component namespace: default spec: clusterIP: None ports: - name: web port: 80 selector: app: custom-component这段输出值得逐项对照验证StatefulSet 主资源replicas: 1、image: nginx:latest来自 Application 的propertiesserviceName、资源name来自context.namevolumeClaimTemplates与容器volumeMounts则是 trait 的 patch 结果——volumeClaimTemplates中accessModes: ReadWriteOnce、存储容量与storageClassName均由 trait 模板推导生成volumeMounts的mountPath与卷名test一一对应trait 的辅助资源第二个资源是组件模板outputs: web渲染出的无头 Service注意其标签trait.oam.dev/type: AuxiliaryWorkload与resourceType: TRAIT——在 KubeVela 的模型里outputs中附加的辅助资源同样按 trait 资源语义打标管理OAM 标签体系所有资源都被注入了app.oam.dev/name: website、app.oam.dev/component: custom-component、app.oam.dev/namespace: default、app.oam.dev/resourceType: WORKLOAD/TRAIT等标签这是 KubeVela 控制器做资源追踪、GC 与状态回写的基础。Dry-Run 的更多用法从 references/cli/dryrun.go 的实现可以看到vela dry-run支持多种增强参数# 通过 -d 指定本地定义文件/目录无需预先 apply 到集群即可参与渲染 vela dry-run -d /definition/directory/or/file/ -f /path/to/app.yaml # 离线模式使用内置 fake client跳过集群校验完全本地渲染 vela dry-run --offline -f app.yaml # 同时渲染策略与工作流文件需 --merge 生效 vela dry-run -f app.yaml -f policy.yaml -f workflow.yaml --merge # 指定定义所在命名空间默认 vela-system vela dry-run -f app.yaml -x vela-system其中-d参数非常适合本示例的验证流程即使尚未执行vela def apply也可以通过vela dry-run -d stateful.cue -d volume-trait.cue -f app.yaml直接在本地完成渲染。离线模式下DryRunApplication会读取定义文件构造 fake client源码见 pkg/appfile/dryrun/dryrun.go 的NewDryRunOption与ExecuteDryRun再调用渲染引擎输出ComponentManifest列表。自定义定义的工作原理从命令到渲染引擎将本次示例涉及的命令与仓库源码对应起来可以得到完整的调用链vela def apply→ references/cli/def.go 的defApplyAll/defApplyOne读取本地 CUE 文件 → 调用pkg/definition的Definition结构pkg/definition/definition.go将 CUE 转换为 ComponentDefinition/TraitDefinition 的 Unstructured 对象 →CreateOrUpdate写入集群指定命名空间vela def vet→ 同一文件中的validateDefinitionFile/validateCueFile通过FromCUEString解析并校验不写集群vela dry-run→ references/cli/dryrun.go 的DryRunApplication读取 Application → 加载定义在线模式下从集群、离线模式下从-d文件构造 fake client→ 调用 pkg/appfile/dryrun/dryrun.go 的ExecuteDryRun执行 CUE 渲染 →PrintDryRun输出 YAML。从类型层面看pkg/definition/definition.go 中component、trait等定义类型会映射为ComponentDefinition、TraitDefinition等不同 CRD KindDefinitionTypeToKind因此同一个 CUE 模板中的type字段决定了它最终成为哪一类 X-Definition 以及可被 Application 的哪个字段components[].type或traits[].type引用。常见误区与注意事项output与patch的区别组件定义用output全量生成资源trait 定义用patch增量修改负载不要在 trait 里用output生成主负载也不要在组件里试图 patch 其他组件。patchKey的合并语义列表 patch 若不指定patchKeyKubeVela 可能执行整体替换而非按键合并多 trait 叠加或多卷声明时容易互相覆盖务必按需声明合并键。参数校验parameter中的字段类型约束会在渲染期生效replicas: int传字符串、volumeClaimTemplates缺必填字段都会导致渲染失败。工作负载适配性本示例的 trait 只 patchspec.template路径仅适用于遵循该 Pod 布局的负载StatefulSet、Deployment 等对无 Pod 模板的资源如 CronJob 的spec.jobTemplate.spec.template需要针对性调整 patch 路径。dry-run 与集群状态在线 dry-run 依赖集群中的定义版本若本地改了定义但未vela def apply请使用-d指向本地定义文件或开启--offline。小结通过 docs/examples/custom-trait 这一教学示例可以完整走通 KubeVela 自定义扩展的经典路径用 CUE 编写ComponentDefinitionoutput渲染主负载 outputs渲染辅助资源 parameter暴露参数用 CUE 编写TraitDefinitionpatch增量修改负载 patchKey控制合并策略用vela def apply下发定义、vela def vet本地校验在 Application 中组合使用并用vela dry-run在部署前确认最终渲染出的 K8s 资源。掌握了这套定义—校验—渲染的方法论就可以将任意 Kubernetes 原生资源封装为 KubeVela 的组件与运维特征让平台用户通过声明式 Application 即可复用。赞分享云原生DevOps运维微服务【免费下载链接】kubevelaThe Modern Application Platform.项目地址https://gitcode.com/gh_mirrors/ku/kubevela点击查看免费下载相关推荐GrapesJS Trait API 完全指南组件特性的定义、读写与自定义渲染GrapesJS Trait API 完全指南组件特性的定义、读写与自定义渲染 GrapesJS 中的 Trait特性 是组件设置面板的核心概念用户前端低代码UI组件OpenCV Contrib 实战自定义 CN Tracker 参数与特征提取器基于 TrackerKCFOpenCV Contrib 实战自定义 CN Tracker 参数与特征提取器基于 TrackerKCF 导读 本教程以 opencv_contrib计算机视觉图像处理深度学习机器学习A2UI 自定义组件示例实战用 Google ADK 构建支持多 Surface 与自定义组件的 A2A 联系人查询 AgentA2UI 自定义组件示例实战用 Google ADK 构建支持多 Surface 与自定义组件的 A2A 联系人查询 Agent 本指南以仓库中 custom人工智能AI AgentAI 应用前端UI组件上一篇如何安全重构关键代码路径Scientist库10个常见问题解答指南下一篇MBUtil快速指南高效管理MBTiles地图瓦片数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考