CUE Components
In this section, it will introduce how to use CUE to declare app components via ComponentDefinition
.
First, generate ComponentDefinition
scaffolds via vela def init
with existed YAML file.
The YAML file:
Generate ComponentDefinition
based on the YAML file:
vela def init stateless -t component --template-yaml ./stateless.yaml -o stateless.cue
It generates a file:
$ cat stateless.cue
stateless: {
annotations: {}
attributes: workload: definition: {
apiVersion: "<change me> apps/v1"
kind: "<change me> Deployment"
}
description: ""
labels: {}
type: "component"
}
template: {
output: {
spec: {
selector: matchLabels: "app.oam.dev/component": "name"
template: {
metadata: labels: "app.oam.dev/component": "name"
spec: containers: [{
name: "name"
image: "image"
}]
}
}
apiVersion: "apps/v1"
kind: "Deployment"
}
outputs: {}
parameters: {}
}
In detail:
.spec.workload
is required to indicate the workload type of this component..spec.schematic.cue.template
is a CUE template, specifically:- The
output
filed defines the template for the abstraction. - The
parameter
filed defines the template parameters, i.e. the configurable properties exposed in theApplication
abstraction (and JSON schema will be automatically generated based on them).
- The
Add parameters in this auto-generated custom component file :
stateless: {
annotations: {}
attributes: workload: definition: {
apiVersion: "<change me> apps/v1"
kind: "<change me> Deployment"
}
description: ""
labels: {}
type: "component"
}
template: {
output: {
spec: {
selector: matchLabels: "app.oam.dev/component": parameter.name
template: {
metadata: labels: "app.oam.dev/component": parameter.name
spec: containers: [{
name: parameter.name
image: parameter.image
}]
}
}
apiVersion: "apps/v1"
}
outputs: {}
parameters: {
name: string
}
}
$ vela def vet stateless.cue
Validation succeed.
Declare another component named task
which is an abstraction for run-to-completion workload.
vela def init task -t component -o task.cue
It generates a file:
$ cat task.cue
task: {
annotations: {}
attributes: workload: definition: {
apiVersion: "<change me> apps/v1"
kind: "<change me> Deployment"
}
description: ""
labels: {}
type: "component"
}
template: {
output: {}
parameter: {}
}
Edit the generated component file:
Apply above ComponentDefinition
files to your Kubernetes cluster:
$ vela def apply stateless.cue
ComponentDefinition stateless created in namespace vela-system.
$ vela def apply task.cue
ComponentDefinition task created in namespace vela-system.
Declare an Application
The ComponentDefinition
can be instantiated in Application
abstraction as below:
apiVersion: core.oam.dev/v1alpha2
kind: Application
metadata:
name: website
spec:
components:
- name: hello
type: stateless
properties:
image: crccheck/hello-world
name: mysvc
- name: countdown
type: task
properties:
image: centos:7
cmd:
- "bin/bash"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"
Above application resource will generate and manage following Kubernetes resources in your target cluster based on the output
in CUE template and user input in Application
properties.
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
... # skip tons of metadata info
spec:
template:
spec:
containers:
- name: mysvc
image: crccheck/hello-world
metadata:
labels:
app.oam.dev/component: mysvc
matchLabels:
app.oam.dev/component: mysvc
---
apiVersion: batch/v1
kind: Job
metadata:
name: countdown
... # skip tons of metadata info
spec:
parallelism: 1
completions: 1
template:
metadata:
name: countdown
spec:
containers:
- name: countdown
image: 'centos:7'
command:
- bin/bash
- '-c'
- for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done
restartPolicy: Never
KubeVela allows you to reference the runtime information of your application via context
keyword.
The most widely used context is application name(context.appName
) component name(context.name
).
context: {
appName: string
name: string
}
parameter: {
image: string
}
output: {
...
spec: {
containers: [{
name: context.name
image: parameter.image
}]
}
...
}
Full available information in CUE context
Composition
It’s common that a component definition is composed by multiple API resources, for example, a webserver
component that is composed by a Deployment and a Service. CUE is a great solution to achieve this in simplified primitives.
KubeVela requires you to define the template of workload type in output
section, and leave all the other resource templates in outputs
section with format as below:
outputs: <unique-name>:
<full template data>
Below is the example for webserver
definition:
Apply to your Kubernetes cluster:
$ vela def apply webserver.cue
ComponentDefinition webserver created in namespace vela-system.
The user could now declare an Application
with it:
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: webserver-demo
namespace: default
spec:
components:
- name: hello-world
type: webserver
properties:
image: crccheck/hello-world
port: 8000
env:
- name: "foo"
value: "bar"
cpu: "100m"
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
hello-world-v1 1/1 1 1 15s
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
What’s Next
Please check the documentation about why we support CUE as first-class templating solution and more details about using CUE efficiently.