kubevela.github.io/docs/end-user/workflow/component-dependency-parame...

8.2 KiB

title
Component Orchestration

This section will introduce the dependencies in components and how to pass data between components.

:::tip We use helm component type in the following examples, make sure you have the fluxcd addon enabled (vela addon enable fluxcd). :::

Dependency

We can use dependsOn to specify the dependencies between components.

For example, component A depends on component B:

...
components:
  - name: A
    type: helm
    dependsOn:
      - B
  - name: B
    type: helm

In this case, KubeVela will deploy B first, and then deploy A when the component B is running.

How to Use

If we want to apply a MySQL cluster, we need:

  1. Apply a secret for MySQL password.
  2. Apply MySQL controller.
  3. Apply MySQL cluster.

Apply the following file:

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: mysql
  namespace: default
spec:
  components:
    - name: mysql-secret
      type: raw
      properties:
        apiVersion: v1
        kind: Secret
        metadata:
          name: mysql-secret
        type: kubernetes.io/opaque
        stringData:
          ROOT_PASSWORD: test
    - name: mysql-controller
      type: helm
      properties:
        repoType: helm
        url: https://presslabs.github.io/charts
        chart: mysql-operator
        version: "0.4.0"
    - name: mysql-cluster
      type: raw
      dependsOn:
        - mysql-controller
        - mysql-secret
      properties:
        apiVersion: mysql.presslabs.org/v1alpha1
        kind: MysqlCluster
        metadata:
          name: mysql-cluster
        spec:
          replicas: 1
          secretName: mysql-secret

Expected Outcome

Check the application in the cluster:

$ vela ls
APP  	COMPONENT       	TYPE	TRAITS	PHASE          	HEALTHY	STATUS	CREATED-TIME
mysql	mysql-secret    	raw 	      	runningWorkflow	       	      	2021-10-14 12:09:55 +0800 CST
├─ 	mysql-controller	helm	      	runningWorkflow	       	      	2021-10-14 12:09:55 +0800 CST
└─ 	mysql-cluster   	raw 	      	runningWorkflow	       	      	2021-10-14 12:09:55 +0800 CST

In the beginning, the status is running workflow since the mysql-controller is not ready.

$ vela ls
APP  	COMPONENT       	TYPE	TRAITS	PHASE  	HEALTHY	STATUS	CREATED-TIME
mysql	mysql-secret    	raw 	      	running	healthy	      	2021-10-14 12:09:55 +0800 CST
├─ 	mysql-controller	helm	      	running	healthy	      	2021-10-14 12:09:55 +0800 CST
└─ 	mysql-cluster   	raw 	      	running	       	      	2021-10-14 12:09:55 +0800 CST

After a while, all components is running successfully. The mysql-cluster will be deployed after mysql-controller and mysql-secret is healthy.

:::info dependsOn use healthy to check status. If the component is healthy, then KubeVela will deploy the next component. If you want to customize the healthy status of the component, please refer to Status Write Back :::

Inputs and Outputs

In KubeVela, we can use inputs and outputs in Components to pass data.

Outputs

Outputs is made of name and valueFrom. Input will use name to reference output.

We can write valueFrom in the following ways:

  1. Use value expression, eg. valueFrom: output.metadata.name. Note that output is a built-in field referring to the resource in the component that is rendered and deployed to the cluster.
  2. Use CUE expressions, eg. use + to combine value and string: valueFrom: output.metadata.name + "testString" or you can import built-in packages in CUE like:
valueFrom: |
          import "strings"
          strings.Join(["1","2"], ",")

Inputs

Inputs is made of from and parameterKey. Input uses from to reference output, parameterKey is a expression that assigns the value of the input to the corresponding field.

eg.

  1. Specify inputs:
...
- name: wordpress
  type: helm
  inputs:
    - from: mysql-svc
      parameterKey: properties.values.externalDatabase.host
  1. The field parameterKey specifies the field path of the parameter key in component to be assigned after rendering:

Which means the input value will be passed into the below properties:

...
- name: wordpress
  type: helm
  properties:
    values:
      externalDatabase:
        host: <input value>

How to Use

In the following we will apply a WordPress server with the MySQL address passed from a MySQL component:

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: wordpress-with-mysql
  namespace: default
spec:
  components:
    - name: mysql
      type: helm
      outputs:
        # the output is the mysql service address
        - name: mysql-svc
          valueFrom: output.metadata.name + ".default.svc.cluster.local"
      properties:
        repoType: helm
        url: https://charts.bitnami.com/bitnami
        chart: mysql
        version: "8.8.2"
        values:
          auth:
            rootPassword: mypassword
    - name: wordpress
      type: helm
      inputs:
        # set the host to mysql service address
        - from: mysql-svc
          parameterKey: properties.values.externalDatabase.host
      properties:
        repoType: helm
        url: https://charts.bitnami.com/bitnami
        chart: wordpress
        version: "12.0.3"
        values:
          mariadb:
            enabled: false
          externalDatabase:
            user: root
            password: mypassword
            database: mysql
            port: 3306

Expected Outcome

Check the application in the cluster:

$ vela ls

APP                 	COMPONENT	TYPE	TRAITS	PHASE          	HEALTHY	STATUS	CREATED-TIME
wordpress-with-mysql	mysql    	helm	running	                healthy	        2021-10-12 18:04:10 +0800 CST
└─                	    wordpress	helm	running	                healthy	       	2021-10-12 18:04:10 +0800 CST

The WordPress with MySQL has been successfully applied.

Multi-cluster Orchestration

In multi-cluster scenario, we can still make use of Dependency and Inputs/Outputs to orchestrate the components. The usage is the same as in the single-cluster scenario. Here's a direct example. Here is a Inputs/Outpus example and Dependency is also available.

How to Use

:::note The environment in example have one managed cluster named cluster-worker. :::

Deploy the following application, which will dispatch a Deployment and a Service. Then deploy a ConfigMap with some status information.

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: cm-with-message
spec:
  components:
    - name: podinfo
      outputs:
        - name: message
          valueFrom: output.status.conditions[0].message
        - name: ip
          valueFrom: outputs.service.spec.clusterIP
      properties:
        image: stefanprodan/podinfo:4.0.3
      type: webservice
      traits:
        - type: expose
          properties:
            port: [ 80 ]
    - name: configmap
      properties:
        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: deployment-msg
      type: raw
      inputs:
        - from: message
          parameterKey: data.msg
        - from: ip
          parameterKey: data.ip
  policies:
    - name: topo
      properties:
        clusters: [ "local","cluster-worker" ]
      type: topology
    - name: override
      properties:
        selector:
          - configmap
          - podinfo
      type: override

Expected Outcome

$ vela status cm-with-message --tree                  
CLUSTER            NAMESPACE     RESOURCE                 STATUS    
cluster-worker─── default    ─┬─ ConfigMap/deployment-msg updated   
                              ├─ Service/podinfo          updated   
                              └─ Deployment/podinfo       updated   
local       ─── default      ─┬─ ConfigMap/deployment-msg updated   
                              ├─ Service/podinfo          updated   
                              └─ Deployment/podinfo       updated   

Check the ConfigMap in the cluster. The same to the other cluster.

$ kubectl get cm deployment-msg -oyaml |grep -C3 ^data
apiVersion: v1
data:
  ip: 10.43.223.14
  msg: Deployment has minimum availability.
kind: ConfigMap