组件模型

组件描述了可以作为更大的分布式应用的一部分的被实例化的功能单元

https://github.com/oam-dev/spec/blob/master/3.component_model.md

本节定义了组件模型。

组件描述了可以作为更大的分布式应用的一部分的被实例化的功能单元。应用部分将描述组件如何被分组,以及这些组件的实例如何被配置,而本节将重点讨论组件模型本身。

modern_app

组件定义

ComponentDefinition 实体的作用是允许组件提供者以基础设施中立的格式声明这种执行单元的运行时特性。

例如,应用程序中的每个微服务都被描述为一个组件。请注意,ComponentDefinition 本身不是该微服务的实例,而是对该微服务的可配置属性的声明。这些可配置的属性应该作为参数列表公开,允许应用团队在以后部署时设置和实例化这个组件。

在实践中,简单的容器化工作负载、Helm图表或云数据库都可以被建模为一个组件。

顶层属性

以下是提供组件定义的顶层信息的属性。

Attribute Type Required Default Value Description
apiVersion string Y 用于标识对象应该具有的模式版本的字符串。核心类型在这个版本的模式中使用core.oam.dev/v1beta1
kind string Y 必须是 ComponentDefinition
metadata Metadata Y 实体元数据.
spec Spec Y 组件定义的规范

Spec

Attribute Type Required Default Value Description
workload WorkloadTypeDescriptor Y 对该组件的工作负载类型 的标识符。
schematic Schematic Y 该组件的原理图信息。

WorkloadTypeDescriptor

Attribute Type Required Default Value Description
type string Y 通过名称对 WorkloadDefinition 的引用。
definition WorkloadGVK Y type相互排斥,通过group, version和kind对WorkloadDefinition的引用。

WorkloadGVK

Attribute Type Required Default Value Description
apiVersion string Y 工作负载类型的API版本。
kind string Y 工作负载类型的API种类。

Schematic

本节声明了组件的示意图,该组件可以在以后的部署工作流程中作为应用程序的一部分被实例化。请注意,OAM本身对如何实现该示意图没有强制要求,只要它能做到。

  1. 建立一个可部署单元的模型。
  2. 暴露一个JSON模式或同等的参数列表。

在KubeVela中,目前支持以下模式的实现(cuehelmkube)。

示例

下面是一个基于CUE的组件定义的完整例子,名为webserver。

apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
  name: webserver
  annotations:
    definition.oam.dev/description: "webserver is a combo of Deployment + Service"
spec:
  workload:
    definition:
      apiVersion: apps/v1
      kind: Deployment
  schematic:
    cue:
      template: |
        output: {
            apiVersion: "apps/v1"
            kind:       "Deployment"
            spec: {
                selector: matchLabels: {
                    "app.oam.dev/component": context.name
                }
                template: {
                    metadata: labels: {
                        "app.oam.dev/component": context.name
                    }
                    spec: {
                        containers: [{
                            name:  context.name
                            image: parameter.image

                            if parameter["cmd"] != _|_ {
                                command: parameter.cmd
                            }

                            if parameter["env"] != _|_ {
                                env: parameter.env
                            }

                            if context["config"] != _|_ {
                                env: context.config
                            }

                            ports: [{
                                containerPort: parameter.port
                            }]

                            if parameter["cpu"] != _|_ {
                                resources: {
                                    limits:
                                        cpu: parameter.cpu
                                    requests:
                                        cpu: parameter.cpu
                                }
                            }
                        }]
                }
                }
            }
        }
        // an extra template
        outputs: service: {
            apiVersion: "v1"
            kind:       "Service"
            spec: {
                selector: {
                    "app.oam.dev/component": context.name
                }
                ports: [
                    {
                        port:       parameter.port
                        targetPort: parameter.port
                    },
                ]
            }
        }
        parameter: {
            image: string
            cmd?: [...string]
            port: *80 | int
            env?: [...{
                name:   string
                value?: string
                valueFrom?: {
                    secretKeyRef: {
                        name: string
                        key:  string
                    }
                }
            }]
            cpu?: string
        }        

在平台上安装了上述网络服务器后,用户将能够在一个应用程序中部署这个组件,如下所示。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: webserver-demo
spec:
  components:
    - name: hello-world
      type: webserver               # claim to deploy webserver component definition
      properties:                   # setting parameter values
        image: crccheck/hello-world
        port: 8000                  # this port will be automatically exposed to public
        env:
        - name: "foo"
          value: "bar"
        cpu: "100m"

其他原理图格式的例子。

  • Helm组件:示例
  • 原始Kubernetes API资源作为组件:样本