资源关联规则

资源关联规则主要规定了:一个类型的 Kubernetes 资源可能包含哪些类型的子资源。它的主要作用是帮助 KubeVela 建立应用所纳管资源的拓扑关系。举例来说,系统中已经内置了这样的一条资源关联规则:Deployment 类型的资源下面的子资源只可能是 ReplicaSet,而 ReplicaSet 的子资源只可能是 Pod。 这样当创建了一个 Deployment 为工作负载的 KubeVela 应用后,在 VelaUX 的资源拓扑图页面查看该应用的拓扑关系视图,KubeVela 就会根据上面的资源关联规则,先列出和 Deployment 同一 namespace 的所有 ReplicaSet 并过滤掉 OwnerReference 不是该 Deployment 的结果,进一步经过一样的过程找出 ReplicaSet 下面的 Pod,从而建立起整个应用下面纳管资源的拓扑层级关系。

总体上这些资源关联规则主要会在以下场景中被用到:

  • 在 VelaUX 的资源拓扑视图中用来展示资源之间的拓扑关系。下面就是一个资源拓扑图的例子:

image

  • 通过 cli 使用 vela port-forward, vela logs, vela exec 以及 vela status --endpoint 或者在 VelaUX 上查看应用下实例的日志或访问端口等功能时,用来发现应用下面的 pod 或 service。

为自定义资源添加关联规则

系统所内置的资源关联规则是有限的,如果系统中添加了新的自定义资源(Kubernetes CustomResource),你可以创建一个 Kubernetes configmap 来为这个类型资源添加关系规则。

接下来我们通过一个实际的例子来讲解资源关联规则的作用。

你可以先通过下面的命令,启用一个尚在实验阶段的插件 kruise

  1. vela addon registry add experimental --type=helm --endpoint=https://addons.kubevela.net/experimental/
  2. vela addon enable kruise

插件启用成功之后,我们就可以看到一个 cloneset 的 componentDefinition,而这个 Definition 创建出来的工作负载是一个 clonesets.apps.kruise.io,最终这个 clonset 会创建出来具体的 pod。

  1. $ vela componets
  2. NAME DEFINITION DESCRIPTION
  3. cloneset autodetects.core.oam.dev Describes long-running, scalable, containerized services
  4. that have a stable network endpoint to receive external
  5. network traffic from customers. If workload type is skipped
  6. for any service defined in Appfile, it will be defaulted to
  7. `webservice` type.

接下来,创建一个 cloneset 的应用如下所示:

  1. cat <<EOF | vela up -f -
  2. apiVersion: core.oam.dev/v1beta1
  3. kind: Application
  4. metadata:
  5. name: app-cloneset
  6. spec:
  7. components:
  8. - name: clone-set
  9. type: cloneset
  10. properties:
  11. cmd:
  12. - ./podinfo
  13. - stress-cpu=1
  14. image: stefanprodan/podinfo:4.0.3
  15. port: 8080
  16. updateStrategyType: InPlaceOnly
  17. EOF

应用创建成功之后,我们在 VelaUX 页面查看该应用时,在资源拓扑页面发现 cloneset 资源下面没有关联任何的资源,并且通过实例列表页面查看到应用下面的 Pod,如下所示:

image

image

同时,如果我们通过 vela logsvela exec 时同样会遇到无法找到实例的问题。如下所示:

  1. $ vela logs app-cloneset
  2. Error: no pod found in your application
  1. $ vela exec app-cloneset
  2. Error: no pod found in your application

其实以上问题的原因都是由于系统添加了一个 cloneset 的自定义资源之后,并没有与之相关的资源关联规则来定义它下面可能有那些类型的子资源。进而在展示资源拓扑图时 KubeVela 不知道该去查找哪些资源类型,也无法找到相应的实例。如果我们通过 kubectl 的命令查看由这个 cloneset 创建 pod 的详细信息会看到这样的结果:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. #...
  5. name: clone-set-vsrj9
  6. namespace: default
  7. ownerReferences:
  8. - apiVersion: apps.kruise.io/v1alpha1
  9. blockOwnerDeletion: true
  10. controller: true
  11. kind: CloneSet
  12. name: clone-set
  13. uid: 817f55d2-a0d8-4efd-be0d-0021e1710dea
  14. spec:
  15. #...

可见,该 pod 的 OwnerReference 就是应用所创建出来的 cloneset。接下来我们为系统添加定义了一个资源关联规则的 configmap 如下所示:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: clone-set-relation
  5. namespace: vela-system
  6. labels:
  7. "rules.oam.dev/resource-format": "yaml"
  8. "rules.oam.dev/resources": "true"
  9. data:
  10. rules: |-
  11. - parentResourceType:
  12. group: apps.kruise.io
  13. kind: CloneSet
  14. childrenResourceType:
  15. - apiVersion: v1
  16. kind: Pod

我们看到,首先这个 configmap 包含了一个特殊的标签 "rules.oam.dev/resources": "true"。只有包含一个这样标签的 configmap 才会被 KubeVela 识别为是一个关于资源关联规则的定义。同时在这个例子中我们还通过一个 "rules.oam.dev/resource-format": "yaml" 注解定义了下面 data.rules 字段所定义的具体规则是通过 YAML 的格式定义的,除了使用 YAML 格式,你还可以使用 JSON 格式来定义这些规则,如下所示:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: clone-set-relation
  5. namespace: vela-system
  6. labels:
  7. "rules.oam.dev/resource-format": "json"
  8. "rules.oam.dev/resources": "true"
  9. data:
  10. rules: |-
  11. [
  12. {
  13. "parentResourceType": {
  14. "group": "apps.kruise.io",
  15. "kind": "CloneSet"
  16. },
  17. "childrenResourceType": [
  18. {
  19. "apiVersion": "v1",
  20. "kind": "Pod"
  21. }
  22. ]
  23. }
  24. ]

上面两个 configmap 作用完全等价。

在这个资源关联规则 configmap 的数据字段(data.rules) 中定义的必须是一个规则列表,单个规则包含了一个父资源类型和一组可能的子资源类型。 在这个例子中,我们定义了一个 apps.kruise.io 组下的 CloneSet 类型资源的子资源是 v1/Pod,这样在展示 CloneSet 的子资源时,就会定向去查找 pod 。

这个 configmap 创建成功之后,再次查看资源拓扑视图和实例列表如下所示:

image

image

我们再次使用 vela logsvela exec 等命令时就不会再遇到的错误,如下所示:

  1. $ vela logs app-cloneset
  2. + clone-set-vsrj9 clone-set
  3. clone-set 2022-08-22T11:53:46.005267600Z {"level":"info","ts":"2022-08-22T11:53:46.002Z","caller":"podinfo/main.go:123","msg":"Starting podinfo","version":"4.0.3","revision":"a2f9216fe43849c3b4844032771ba632307d8738","port":"9898"}

同样的,如果你的某个自定义资源会创建 Kubernetes service ,你也可以为系统添加一个资源关联规则,从而支持查找应用的访问端点的功能: vela status --endpoints

集成在插件当中

经过上面的介绍相信你应该已经想到,如果一个 KubeVela 插件中安装了某种自定义资源,你就可以通过在插件中添加一个这样的 configmap 来建立这个它与其他资源的关联规则。 具体方法是在插件的应用模版文件中的 outputs 定义一个资源关联规则的 configmap。例如:

  1. package main
  2. output: {
  3. apiVersion: "core.oam.dev/v1beta1"
  4. kind: "Application"
  5. spec: {
  6. }
  7. ...
  8. }
  9. outputs: resourceTree: {
  10. apiVersion: "v1"
  11. kind: "ConfigMap"
  12. metadata: {
  13. name: "resource-tree"
  14. namespace: "vela-system"
  15. labels: {
  16. "rules.oam.dev/resources": "true"
  17. "rules.oam.dev/resource-format": "json"
  18. }
  19. }
  20. data: rules: json.Marshal(_rules)
  21. }
  22. _rules: {...}

具体请参考文档