编辑管理模块定义

编辑管理模块定义 - 图1提示

开始之前,请确保你已经阅读了模块定义相关概念。

在 KubeVela CLI 工具中,vela def 命令组为开发者提供了一系列便捷的模块定义 X-Definition 编写工具,使得扩展模块的编写可以全部在 CUE 文件中进行,避免将 Template CUE 与 Kubernetes 的 YAML 格式进行混合,方便进行格式化与校验。

vela def init 是一个用来帮助用户初始化新的 Definition 的脚手架命令。用户可以通过 如下命令来创建一个新的空白 TraitDefinition。

  1. vela def init my-trait -t trait --desc "My trait description."

它生成的文件为:

  1. "my-trait": {
  2. annotations: {}
  3. attributes: {
  4. appliesToWorkloads: []
  5. conflictsWith: []
  6. definitionRef: ""
  7. podDisruptive: false
  8. workloadRefPath: ""
  9. }
  10. description: "My trait description."
  11. labels: {}
  12. type: "trait"
  13. }
  14. template: patch: {}

你也可以采用交互式的方式创建:

  1. vela def init my-comp --interactive

交互过程

  1. Please choose one definition type from the following values: component, trait, policy, workload, scope, workflow-step
  2. > Definition type: component
  3. > Definition description: My component definition.
  4. Please enter the location the template YAML file to build definition. Leave it empty to generate default template.
  5. > Definition template filename:
  6. Please enter the output location of the generated definition. Leave it empty to print definition to stdout.
  7. > Definition output filename: my-component.cue
  8. Definition written to my-component.cue

除此之外,如果用户创建 ComponentDefinition 的目的是一个 Deployment(或者是其他的 Kubernetes Object ),而这个 Deployment 已经有了 YAML 格式的模版,用户还可以通过 --template-yaml 参数来完成从 YAML 到 CUE 的自动转换。例如如下的 my-deployment.yaml

  1. # my-deployment.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: hello-world
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app.kubernetes.io/name: hello-world
  11. template:
  12. metadata:
  13. labels:
  14. app.kubernetes.io/name: hello-world
  15. spec:
  16. containers:
  17. - name: hello-world
  18. image: somefive/hello-world
  19. ports:
  20. - name: http
  21. containerPort: 80
  22. protocol: TCP
  23. ---
  24. apiVersion: v1
  25. kind: Service
  26. metadata:
  27. name: hello-world-service
  28. spec:
  29. selector:
  30. app: hello-world
  31. ports:
  32. - name: http
  33. protocol: TCP
  34. port: 80
  35. targetPort: 8080
  36. type: LoadBalancer

运行如下命令可以得到 CUE 格式的 ComponentDefinition

  1. vela def init my-comp -t component --desc "My component." --template-yaml ./my-deployment.yaml

得到的结果如下:

  1. "my-comp": {
  2. annotations: {}
  3. attributes: workload: definition: {
  4. apiVersion: "<change me> apps/v1"
  5. kind: "<change me> Deployment"
  6. }
  7. description: "My component."
  8. labels: {}
  9. type: "component"
  10. }
  11. template: {
  12. output: {
  13. metadata: name: "hello-world"
  14. spec: {
  15. replicas: 1
  16. selector: matchLabels: "app.kubernetes.io/name": "hello-world"
  17. template: {
  18. metadata: labels: "app.kubernetes.io/name": "hello-world"
  19. spec: containers: [{
  20. name: "hello-world"
  21. image: "somefive/hello-world"
  22. ports: [{
  23. name: "http"
  24. containerPort: 80
  25. protocol: "TCP"
  26. }]
  27. }]
  28. }
  29. }
  30. apiVersion: "apps/v1"
  31. kind: "Deployment"
  32. }
  33. outputs: "hello-world-service": {
  34. metadata: name: "hello-world-service"
  35. spec: {
  36. ports: [{
  37. name: "http"
  38. protocol: "TCP"
  39. port: 80
  40. targetPort: 8080
  41. }]
  42. selector: app: "hello-world"
  43. type: "LoadBalancer"
  44. }
  45. apiVersion: "v1"
  46. kind: "Service"
  47. }
  48. parameter: {}
  49. }

接下来,用户就可以在该文件的基础上进一步做进一步的修改了。比如将属性中对于 workload.definition 中的 <change me> 去掉。

在初始化 Definition 文件之后,可以运行 vela def vet my-comp.cue 来校验 Definition 是否在语法上有错误。

  1. vela def vet my-comp.cue

比如如果少写了一个括号,该命令能够帮助用户识别出来。

确认 Definition 撰写无误后,开发者就可以将模块部署到控制面集群中了。

  1. vela def apply my-comp.cue -n my-namespace

将该 Definition 将部署到 Kubernetes 的 my-namespace 命名空间中。默认情况下,如果不指定 namespace,就会部署到 vela-system 命名空间。

编辑管理模块定义 - 图2提示

如果模块定义被部署到 vela-system 意味着这个模块全局可用,而指定到其他命名空间的模块只有在该命名空间可用,这个功能可以用于多租户场景。

如果想了解一下 CUE 格式的 Definition 文件会被渲染成什么样的 Kubernetes YAML 文件,可以使用 --dry-run来预先渲染成 Kubernetes API YAML 进行确认。

  1. vela def apply my-comp.cue --dry-run

expected output

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: ComponentDefinition
  3. metadata:
  4. annotations:
  5. definition.oam.dev/description: My component.
  6. labels: {}
  7. name: my-comp
  8. namespace: vela-system
  9. spec:
  10. schematic:
  11. cue:
  12. template: |
  13. output: {
  14. metadata: name: "hello-world"
  15. spec: {
  16. replicas: 1
  17. selector: matchLabels: "app.kubernetes.io/name": "hello-world"
  18. template: {
  19. metadata: labels: "app.kubernetes.io/name": "hello-world"
  20. spec: containers: [{
  21. name: "hello-world"
  22. image: "somefive/hello-world"
  23. ports: [{
  24. name: "http"
  25. containerPort: 80
  26. protocol: "TCP"
  27. }]
  28. }]
  29. }
  30. }
  31. apiVersion: "apps/v11"
  32. kind: "Deployment"
  33. }
  34. outputs: "hello-world-service": {
  35. metadata: name: "hello-world-service"
  36. spec: {
  37. ports: [{
  38. name: "http"
  39. protocol: "TCP"
  40. port: 80
  41. targetPort: 8080
  42. }]
  43. selector: app: "hello-world"
  44. type: "LoadBalancer"
  45. }
  46. apiVersion: "v1"
  47. kind: "Service"
  48. }
  49. parameter: {}
  50. workload:
  51. definition:
  52. apiVersion: apps/v1
  53. kind: Deployment

在 apply 命令后,开发者可以采用原生的 kubectl get 从 Kubernetes 集群中查看对结果进行确认,但是正如我们上文提到的,YAML 格式的结果会相对复杂,并且嵌套在 YAML 中的 CUE 字符串会比较难编辑。使用 vela def get 命令可以自动将其转换成 CUE 格式,方便用户查看。

  1. vela def get my-comp

用户可以通过列表查询查看当前系统中安装的所有 Definition。

  1. vela def list

也可以指定类型筛选:

  • 按组件筛选

    1. vela def list -t component
  • 按运维特征筛选

    1. vela def list -t trait
  • 按工作流步骤筛选

    1. vela def list -t workflow-step
  • 按策略筛选

    1. vela def list -t policy

你可以使用 vela def edit 命令来编辑 Definition 时,用户也只需要对转换过的 CUE 格式 Definition 进行修改,该命令会自动完成格式转换。用户也可以通过设定环境变量 EDITOR 来使用自己想要使用的编辑器。

  1. $ EDITOR=vim vela def edit my-comp

用户可以运行 vela def del 来删除相应的 Definition。

  1. $ vela def del my-comp -n my-namespace
  2. Are you sure to delete the following definition in namespace my-namespace?
  3. ComponentDefinition my-comp: My component.
  4. [yes|no] > yes
  5. ComponentDefinition my-comp in namespace my-namespace deleted.

下图简单展示了如何使用vela def命令来操作管理 Definition。

def-demo

当我们希望通过实际的应用调试模块定义的时候,我们可以使用 vela dry-run --definitions 命令(-d 是缩写)指定本地的模块定义文件执行应用渲染。

Dry-run 命令可以帮助你清晰的查看实际运行到 Kubernetes 的资源是什么。换句话说,你可以在本地看到 KubeVela 控制器运行的结果。

举例来说,我们使用 dry-run 运行如下应用:

  1. # app.yaml
  2. apiVersion: core.oam.dev/v1beta1
  3. kind: Application
  4. metadata:
  5. name: vela-app
  6. spec:
  7. components:
  8. - name: express-server
  9. type: my-comp

命令如下:

  1. vela dry-run -f app.yaml -d my-comp.cue

编辑管理模块定义 - 图4警告

注意,在 CLI 1.6.2 之前,你的模块定义需要先转换成 Kubernetes API 的 YAML 格式才能用 dry-run。

  1. vela dry-run -f app.yaml -d my-comp.yaml

期望输出

  1. ---
  2. # Application(vela-app) -- Component(express-server)
  3. ---
  4. apiVersion: apps/v1
  5. kind: Deployment
  6. metadata:
  7. annotations: {}
  8. labels:
  9. app.oam.dev/appRevision: ""
  10. app.oam.dev/component: express-server
  11. app.oam.dev/name: vela-app
  12. app.oam.dev/namespace: default
  13. app.oam.dev/resourceType: WORKLOAD
  14. workload.oam.dev/type: my-comp
  15. name: hello-world
  16. namespace: default
  17. spec:
  18. replicas: 1
  19. selector:
  20. matchLabels:
  21. app.kubernetes.io/name: hello-world
  22. template:
  23. metadata:
  24. labels:
  25. app.kubernetes.io/name: hello-world
  26. spec:
  27. containers:
  28. - image: somefive/hello-world
  29. name: hello-world
  30. ports:
  31. - containerPort: 80
  32. name: http
  33. protocol: TCP
  34. ---
  35. ## From the auxiliary workload
  36. apiVersion: v1
  37. kind: Service
  38. metadata:
  39. annotations: {}
  40. labels:
  41. app.oam.dev/appRevision: ""
  42. app.oam.dev/component: express-server
  43. app.oam.dev/name: vela-app
  44. app.oam.dev/namespace: default
  45. app.oam.dev/resourceType: TRAIT
  46. trait.oam.dev/resource: hello-world-service
  47. trait.oam.dev/type: AuxiliaryWorkload
  48. name: hello-world-service
  49. namespace: default
  50. spec:
  51. ports:
  52. - name: http
  53. port: 80
  54. protocol: TCP
  55. targetPort: 8080
  56. selector:
  57. app: hello-world
  58. type: LoadBalancer
  59. ---

Last updated on 2023年8月4日 by Daniel Higuero