Version: v1.0

定义CRD

在本部分中,我们会对 ComponentDefinitionTraitDefinition 进行详细介绍。

所有的定义对象都应由平台团队来进行维护和安装。在此背景下,可以把平台团队理解为平台中的能力提供者

概述

本质上,KubeVela 中的定义对象由三个部分组成:

  • 能力指示器 (Capability Indicator)
    • ComponentDefinition 使用 spec.workload 指出此组件的 workload 类型.
    • TraitDefinition 使用 spec.definitionRef 指出此 trait 的提供者。
  • 互操作字段 (Interoperability Fields)
    • 他们是为平台所设计的,用来确保给定的 workload 类型可以和某个 trait 一起工作。因此只有 TraitDefinition 有这些字段。
  • 能力封装和抽象 (Capability Encapsulation and Abstraction) (由 spec.schematic 定义)
    • 它定义了此 capability 的模板和参数 ,比如封装。

因此,定义对象的基本结构如下所示:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: XxxDefinition
  3. metadata:
  4. name: <definition name>
  5. spec:
  6. ...
  7. schematic:
  8. cue:
  9. # cue template ...
  10. helm:
  11. # Helm chart ...
  12. # ... interoperability fields

我们接下来详细解释每个字段。

能力指示器 (Capability Indicator)

ComponentDefinition 中,workload 类型的指示器被声明为 spec.workload

下面的示例是在 KubeVela 中,一个给 Web Service 的定义:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: ComponentDefinition
  3. metadata:
  4. name: webservice
  5. namespace: default
  6. annotations:
  7. definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers."
  8. spec:
  9. workload:
  10. definition:
  11. apiVersion: apps/v1
  12. kind: Deployment
  13. ...

在上面的示例中,它声称利用 Kubernetes 的 Deployment (apiVersion: apps/v1, kind: Deployment)作为组件的 workload 类型。

互操作字段 (Interoperability Fields)

只有 trait 有互操作字段。在一个 TraitDefinition 中,互操作字段的大体示例如下所示:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: TraitDefinition
  3. metadata:
  4. name: ingress
  5. spec:
  6. appliesToWorkloads:
  7. - deployments.apps
  8. - webservice
  9. conflictsWith:
  10. - service
  11. workloadRefPath: spec.wrokloadRef
  12. podDisruptive: false

我们来详细解释一下。

.spec.appliesToWorkloads

该字段定义了此 trait 允许应用于哪些类型的 workload 的约束。

  • 它使用一个字符串的数组作为其值。
  • 数组中的每一个元素指向允许应用此 trait 的一个或一组 workload 类型。

有四种来表示一个或者一组 workload 类型。

  • ComponentDefinition 命名, 例如 webserviceworker
  • ComponentDefinition 定义引用(CRD 命名),例如 deployments.apps
  • *.为前缀的 ComponentDefinition 定义引用的资源组,例如*.apps*.oam.dev。这表示 trait 被允许应用于该组中的任意 workload。
  • * 表示 trait 被允许应用于任意 workload。

如果省略此字段,则表示该 trait 允许应用于任意 workload 类型。

如果将一个 trait 应用于未包含在 appliesToWorkloads 中的 workload,KubeVela 将会报错。

.spec.conflictsWith

如果将某些种类的 trait 应用于该 workload,该字段定义了其中哪些 trait 与该 trait 冲突的约束。

  • 它使用一个字符串的数组作为其值。
  • 数组中的每一个元素指向一个或一组 trait。

有四种来表示一个或者一组 workload 类型。

  • TraitDefinition 命名,比如 ingress
  • *.为前缀的 TraitDefinition 定义引用的资源组,例如*.networking.k8s.io。这表示当前 trait 与该组中的任意 trait 相冲突。
  • * 表示当前 trait 与任意 trait 相冲突。

如果省略此字段,则表示该 trait 没有和其他任何 trait 相冲突。

.spec.workloadRefPath

该字段定义 trait 的字段路径,该路径用于存储对其应用 trait 的 workload 的引用。

  • 它使用一个字符串作为其值,比如 spec.workloadRef.

如果设置了此字段,KubeVela core 会自动将 workload 引用填充到 trait 的目标字段中。然后,trait controller 可以之后从 trait 中获取 workload 引用。因此,此字段通常和 trait 一起出现,其 controller 在运行时依赖于 workload 引用。

如何设置此字段的具体细节,请查阅 scaler trait 作为演示。

.spec.podDisruptive

此字段定义了添加或者更新 trait 会不会破坏 pod。在此示例中,因为答案是不会,所以该字段为 false,当添加或更新 trait 时,它不会影响 pod。如果此字段是 true,则它会导致 pod 在 trait 被添加或者更新时被破坏并重启。默认情况下,该值为 false,这意味着该 trait 不会影响 pod。请小心处理此字段。对于严肃的大规模生产使用场景而言,它非常重要和有用。

能力封装和抽象 (Capability Encapsulation and Abstraction)

给定的能力的模板和封装被定义在 spec.schematic 字段中。如下所示范例是一个 KubeVela 中的Web Service 类型的完整定义:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: ComponentDefinition
  3. metadata:
  4. name: webservice
  5. namespace: default
  6. annotations:
  7. definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers."
  8. spec:
  9. workload:
  10. definition:
  11. apiVersion: apps/v1
  12. kind: Deployment
  13. schematic:
  14. cue:
  15. template: |
  16. output: {
  17. apiVersion: "apps/v1"
  18. kind: "Deployment"
  19. spec: {
  20. selector: matchLabels: {
  21. "app.oam.dev/component": context.name
  22. }
  23. template: {
  24. metadata: labels: {
  25. "app.oam.dev/component": context.name
  26. }
  27. spec: {
  28. containers: [{
  29. name: context.name
  30. image: parameter.image
  31. if parameter["cmd"] != _|_ {
  32. command: parameter.cmd
  33. }
  34. if parameter["env"] != _|_ {
  35. env: parameter.env
  36. }
  37. if context["config"] != _|_ {
  38. env: context.config
  39. }
  40. ports: [{
  41. containerPort: parameter.port
  42. }]
  43. if parameter["cpu"] != _|_ {
  44. resources: {
  45. limits:
  46. cpu: parameter.cpu
  47. requests:
  48. cpu: parameter.cpu
  49. }
  50. }
  51. }]
  52. }
  53. }
  54. }
  55. }
  56. parameter: {
  57. // +usage=Which image would you like to use for your service
  58. // +short=i
  59. image: string
  60. // +usage=Commands to run in the container
  61. cmd?: [...string]
  62. // +usage=Which port do you want customer traffic sent to
  63. // +short=p
  64. port: *80 | int
  65. // +usage=Define arguments by using environment variables
  66. env?: [...{
  67. // +usage=Environment variable name
  68. name: string
  69. // +usage=The value of the environment variable
  70. value?: string
  71. // +usage=Specifies a source the value of this var should come from
  72. valueFrom?: {
  73. // +usage=Selects a key of a secret in the pod's namespace
  74. secretKeyRef: {
  75. // +usage=The name of the secret in the pod's namespace to select from
  76. name: string
  77. // +usage=The key of the secret to select from. Must be a valid secret key
  78. key: string
  79. }
  80. }
  81. }]
  82. // +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
  83. cpu?: string
  84. }

schematic 的技术规范在接下来的 CUE 和 Helm 相关的文档中有详细解释。

同时,schematic 字段使你可以直接根据他们来渲染UI表单。详细操作请见从定义中生成表单部分。