Build Your Own Addon
The picture below shows what KubeVela does when an addon is enabled. There are mainly three process:
- Addon Registry store addons which can be used to share and distribute addons anywhere, it can be any git repo, OSS bucket or OCI registry.
- When an addon is enabled through UX/CLI, it will pull these resource files from the Addon Registry, render them and create a KubeVela application.
- Finally, the KubeVela controller take care the rest things and deliver the addon as a normal application into control plane or multi-clusters.
Build an addon
To build an addon, you should follow some basic rules as follows.
You need to create an addon directory to place addon resource files. Won't bother to create? vela addon init
command will create a basic structure for you (vela CLI v1.5 or later). Please refer to vela addon init -h
for details. For quick starts, we will just use vela addon init your-addon-name
now.
Typically, the directory hierarchy looks like below:
├── resources/
│ ├── xxx.cue
│ ├── xxx.yaml
│ └── parameter.cue
├── definitions/
├── schemas/
├── README.md
├── metadata.yaml
└── template.yaml
Not all of these directories or files are necessary, let's explain them one by one.
metadata.yaml(Required)
A metadata.yaml
describes the basic information of an addon, such as the name, version, description, etc. With this basic info, an addon can be recognized by UX/CLI, an example likes:
name: example
version: 1.0.0
description: Example adddon.
icon: xxx
url: xxx
tags:
- only_example
deployTo:
runtimeCluster: false
dependencies:
- name: addon_name
system:
vela: ">=v1.4.0"
kubernetes: ">=1.19.0-0"
needNamespace:
- flux-system
invisible: false
Here's the usage of every field:
Field | Required | Type | Usage |
---|---|---|---|
name | yes | string | The name of the addon. |
version | yes | string | The version of addon, increase for every changes and follow SemVer rule. |
description | yes | string | Description of the addon. |
icon | no | string | Icon of the addon, will display in addon dashboard. |
url | no | string | The official website of the project behind the addon. |
tags | no | []string | The tags to display and organize the addon. |
deployTo.runtimeCluster | no | bool | By default, the addon will not be installed in the managed clusters. If it's true , it will be delivered to all managed clusters automatically. |
dependencies | no | []{ name: string } | Names of other addons it depends on. KubeVela will make sure these dependencies are enabled before installing this addon. |
system.vela | no | string | Required version of vela controller, vela CLI will block the installation if vela controller can't match the requirements. |
system.kubernetes | no | string | Required version of Kubernetes, vela CLI will block the installation if Kubernetes cluster can't match the requirements. |
needNamespace | no | []string | Vela will create these namespaces needed for addon in every clusters before installation. |
invisible | no | bool | If true , the addon won't be discovered by users. It's useful for tests when addon is in draft state. |
README.md(Required)
The README of this addon, it will be displayed in the dashboard for end user who's going to install this addon. So you should let them understand the basic knowledge of the addon which contains:
- What is the addon?
- Why to use this addon? The use case and scenarios.
- How to use this addon? It is the
end user
who should understand. An end to end demo is recommended. - What will be installed? The definitions along with the CRD controllers behind.
There're no restrict rules for an experimental addon, but if the addon want to be verified, the README is the most important thing.
template.yaml(Optional)
An addon is actually a KubeVela Application in the system, so you can also define the application by using the template.yaml
.
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: velaux
namespace: vela-system
spec:
# component definition of resource dir .
You can describe anything in the application if you want, the rest resources defined in other folders will be automatically rendered and appended into this template as components.
The name of Application in template will be replaced by the addon name in metadata.yaml
. The addon application will always have a unified name in the format of addon-<addon_name>
.
If the addon will be installed in managed clusters, please don't define policies or workflow steps in the template, or it will break the automatic precess built internally for addon installation.
Examples
- velaux, define only the header of application in the template.
- OCM control plane, the addon only be installed in control plane, so it just defines everything in the application template.
resources/
directory(Optional)
Addon is actually an Application, but it provides more convenience for you to compose a complex application. You can use CUE or YAML to render resources into an application. This is what resources
directory does for you.
Files defined in resources
folder eventually rendered as components in the application described in template.yaml
.
CUE format resource
If you need to add a component to your application that needs to be rendered dynamically based on parameters when enabled, you can write a CUE format file as shown below:
output: {
type: "webservice"
properties: {
image: "oamdev/vela-apiserver:v1.4.0"
}
traits:[{
type: "service-account"
properties: name: "serviceAccountName"
}]
}
You can refer to the CUE basic to learn language details.
The output
is the keywords of addon, contents defined in output will be rendered as component of application.
The result of the example will be as follows in YAML:
kind: Application
...
# application header in template
spec:
components:
- type: webservice
properties:
image: "oamdev/vela-apiserver:v1.4.0"
traits:
- type: service-account
properties:
name: serviceAccountName
The detail of the example is velaux.
Define parameter for addon
When the resource is defined in CUE, you can also define parameters for addon by writing a parameter.cue
file in the resources folder as shown below:
parameter: {
serviceAccountName: string
}
It can cooperate with the resource file in CUE, here we have a CUE file vela-apiserver.cue
:
output: {
type: "webservice"
properties: {
image: "oamdev/vela-apiserver:v1.4.0"
}
traits:[{
type: "service-account"
properties: name: parameter.serviceAccountName
}]
}
When an end user enabling the addon, he will be able to specify parameters:
vela addon enable velaux serviceAccountName="my-account"
Then the render result will be:
kind: Application
...
# application header in template
spec:
components:
- type: webservice
name: api-server
properties:
image: "oamdev/vela-apiserver:v1.4.0"
traits:
- type: service-account
properties:
name: my-account
Please notice The name of component is the same with file name in the resource/
folder with file type suffix trimmed.
Use context render component
Besides using parameter
to generate component dynamically, you can also use context
to render runtime variable.
For example, you can define the component with cue like this:
output: {
type: "webservice"
properties: {
image: "oamdev/vela-apiserver:" + context.metadata.version
....
}
}
And the metadata.yaml
is:
...
name: velaux
version: 1.2.4
...
The render will be:
kind: Application
...
# application header in template
spec:
components:
- type: webservice
properties:
image: "oamdev/vela-apiserver:v1.2.4"
The image tag becomes the addon's version due to the context.metadata.version
points to. The real example is VelaUX.
Other available fields please refer to metadata.
UX/CLI renders all CUE files , parameter.cue
and data defined in metadata.yaml
in one context when the addon is enabled, resulting in a set of components that are appended to the application template.
YAML format resource
The YAML format resources is just a Kubernetes YAML object, you can define any object one by one in a file.
It will be directly added to the application as a K8s-object
type component during rendering.
For example, the OCM addon defines all it's resources in the addon. All these YAML objects will be rendered as components in an Application.
definitions/
directory(Optional)
You can create a definition's file directory under the Addon Registry to store template definition files such as component definitions, trait definitions, and workflowstep definitions. It should be noted that since the KubeVela controller is usually not installed in the managed cluster, even if the addon is enabled by setting the deployTo.runtimeCluster
field in the metadata file (metadata.yaml) to install the addon in the subcluster, the template definition file will not be distributed to sub-clusters.
For example, the fluxcd
addon defines multiple ComponentDefinition and TraitDefinition.
schemas/
directory(Optional)
The schemas directory is used to store the UI schema files corresponding to Definitions
, which is used to enhance the display effect when displaying the parameters required by Definitions
in UX.
The above is a complete introduction to how to make an addon, you can find the complete description of the above-mentioned addon in this catalog example.
In addition to uploading the addon resource files to your addon repository, you can also submit a pull request to KubeVela community addon repository and experimental addon repository to addon new addons. After pr merged your addons can be discovered and used by other KubeVela users.
Install Addon Locally
You can install addon from local to debug your own addon:
vela addon enable ./your-addon-dir/
Known Limits
- Cannot only install addon in the sub-clusters. Because of KubeVela need render out every kind of resource in control plane, if an addon contain some CRD, these CRD must be installed in control plane, otherwise Vela-core controller will meet an error of cannot find CRD.
Extend Terraform Addon
- We have built some tools to extend cloud resource as addons for convenience, you can refer to the extend terraform addon docs.
Contribution
If you have developed your own addons, welcome to contribute to the community catalog.
Meanwhile, any bugfix of existing addons are welcomed. Just make a pull request to this repo.