Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to launch a new function for your K8s PaaS

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

In this issue, the editor will bring you a new function about how to put your K8s PaaS online. The article is rich in content and analyzes and narrates it from a professional point of view. I hope you can get something after reading this article.

Here's how to "launch" a new capability for your KubeVela-based PaaS in 20 minutes.

Before you officially begin, please make sure that you have installed KubeVela and its dependent K8s environment correctly.

The basic structure of KubeVela extension

The basic architecture of KubeVela is shown in the figure:

To put it simply, KubeVela extends the capabilities for users by adding Workload Type and Trait, and the service providers of the platform expose the extended functions up through Appfile through the registration and extension of Definition files. The basic writing process is also given in the official documentation, two of which are extension examples of Workload and one is an extension example of Trait:

Workload Type extension of OpenFaaS as an example

Workload Type extension of Cloud Resource RDS as an example

Trait extension of KubeWatch as an example

Let's take a built-in WorkloadDefinition as an example to introduce the basic structure of the Definition file:

ApiVersion: core.oam.dev/v1alpha2kind: WorkloadDefinitionmetadata: name: webservice annotations: definition.oam.dev/description: "`Webservice` is a workload type to describe long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers. If workload type is skipped for any service defined in Appfile It will be defaulted to `Web Service` type. "spec: definitionRef: name: deployments.apps extension: 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} parameter: {/ / + usage=Which image would you like to use for your service / / + short=i image: string / / + usage=Commands to run in the container cmd?: [. String] / / + usage=Which port do you want customer traffic sent to / / + short=p port: * 80 | int / / + usage=Define arguments by using environment variables env?: [. {/ + usage=Environment variable name name: string / / + usage=The value of the environment variable value?: string / / + usage=Specifies a source the value Of this var should come from valueFrom?: {/ + usage=Selects a key of a secret in the pod's namespace secretKeyRef: {/ / + usage=The name of the secret in the pod's namespace to select from name: string / / + usage=The key of the secret to select from. Must be a valid secret key key: string}] / / + usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core) cpu?: string}

At first glance, it looks long and complicated, but don't worry, in fact, it is divided into two parts:

Definition registration section without extension field

Extension template (CUE Template) section for Appfile

Let's take it apart and introduce it slowly, but it's actually very easy to learn.

Definition registration section apiVersion: core.oam.dev/v1alpha2kind: WorkloadDefinitionmetadata: name: webservice annotations: definition.oam.dev/description: "`Webservice` is a workload type to describe long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers. If workload type is skipped for any service defined in Appfile, it will be defaulted to `Web Service` type." spec: definitionRef: name: deployments.apps

This section is full of 11 lines, of which 3 lines introduce the functions of webservice and 5 lines are in a fixed format. Only 2 lines have specific information:

DefinitionRef: name: deployments.apps

These two lines represent the name of the CRD behind the Definition in the format of.. Students who know K8s should know that what is commonly used in K8s is to locate resources through api-group, version and kind, while kind corresponds to resources in K8s restful API. For example, if you are familiar with Deployment and ingress, the corresponding relationship is as follows:

Add a little knowledge here, why add the concept of resources when you have kind? Because a CRD has some fields like status,replica in addition to the kind itself, which you want to decouple from the spec itself and update separately in the restful API, resources will also have some additional resources in addition to the corresponding kind, such as the status representation of Deployment as deployments/status.

So believe that smart you have understood how to write Definition without extension, the easiest thing is to splice it according to the resource combination of K8s, just fill in the blanks of the following three angle brackets.

ApiVersion: core.oam.dev/v1alpha2kind: WorkloadDefinitionmetadata: name: spec: definitionRef: name:.

The same is true for operation and maintenance feature registration (TraitDefinition).

ApiVersion: core.oam.dev/v1alpha2kind: TraitDefinitionmetadata: name: spec: definitionRef: name:.

So writing Ingress as an extension of KubeVela is as follows:

ApiVersion: core.oam.dev/v1alpha2kind: TraitDefinitionmetadata: name: ingressspec: definitionRef: name: ingresses.networking.k8s.io

In addition, some other functional model layer functions have been added to TraitDefinition, such as:

AppliesToWorkloads: indicates which Workload types this trait can be applied to.

ConflictWith: indicates which other types of trait this trait conflicts with.

WorkloadRefPath: indicates which workload field the trait contains, and the KubeVela is automatically populated when the trait object is generated. ...

These features are optional and will not be used in this article. We will introduce them in more detail in other articles that follow.

So at this point, I'm sure you've mastered a basic extension pattern without extensions, and the rest is an abstract template around CUE.

Extension template (CUE Template) section for Appfile

Students who are interested in CUE itself can refer to this basic introduction to CUE to learn more. Limited to the space of this article, the CUE itself is not carried out in detail.

We all know that KubeVela's Appfile is very concise to write, but the object of K8s is a relatively complex YAML, and in order to maintain simplicity without losing extensibility, KubeVela provides a bridge from complexity to simplicity. This is the role of CUE Template in Definition.

CUE format template

Let's first look at a Deployment YAML file, as shown below, many of which are fixed frames (template parts), and what you really need to fill in are only a few fields (parameters).

ApiVersion: apps/v1kind: Deploymentmeadata: name: mytestspec: template: spec: containers:-name: mytest env:-name: a value: B image: nginx:v1 metadata: labels: app.oam.dev/component: mytest selector: matchLabels: app.oam.dev/component: mytest

In KubeVela, the fixed format of Definition files is divided into two parts: output and parameter. The content in output is the "template part", and parameter is the parameter part.

Then let's rewrite the above Deployment YAML into the format of the template in Definition.

Output: {apiVersion: "apps/v1" kind: "Deployment" metadata: name: "mytest" spec: {selector: matchLabels: {"app.oam.dev/component": "mytest"} template: {metadata: labels: {"app.oam.dev/component": "mytest" } spec: {containers: [{name: "mytest" image: "nginx:v1" env: [{name: "a" Value: "b"}]}

This format is very similar to json, in fact this is the format of CUE, and CUE itself is a superset of json. In other words, the format of CUE adds some simple rules to make it easier to read and use on the basis of meeting the JSON rules:

The annotation style of C language.

Double quotation marks that represent field names can be defaulted without special symbols.

The comma at the end of the field value can be defaulted, and there will be no error if you write the comma at the end of the field.

The outermost braces can be omitted.

Template parameters in CUE format-variable references

After writing the template section, let's build the parameter section, which is actually a reference to the variable.

Parameter: {name: string image: string} output: {apiVersion: "apps/v1" kind: "Deployment" 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}]}

As shown in the example above, the template parameters in KubeVela are done through the parameter section, and parameter essentially replaces some fields in output as references.

Complete Definition and use in Appfile

In fact, with the combination of the above two parts, we can write a complete Definition file:

ApiVersion: core.oam.dev/v1alpha2kind: WorkloadDefinitionmetadata: name: mydeployspec: definitionRef: name: deployments.apps extension: template: | parameter: {name: string image: string} output: {apiVersion: "apps/v1" kind: "Deployment" 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}]}

In order to facilitate debugging, you can generally divide it into two files in advance, one of which is placed in the previous yaml section, assuming that it is named def.yaml, such as:

ApiVersion: core.oam.dev/v1alpha2kind: WorkloadDefinitionmetadata: name: mydeployspec: definitionRef: name: deployments.apps extension: template: |

The other is to put the cue file, assuming that it is named def.cue:

Parameter: {name: string image: string} output: {apiVersion: "apps/v1" kind: "Deployment" 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}]}

First, format the def.cue. At the same time, the cue tool itself will do some verification, or you can debug it more deeply through the cue command:

Cue fmt def.cue

After debugging, you can assemble the yaml through a script:

. / hack/vela-templates/mergedef.sh def.yaml def.cue > mydeploy.yaml

Then apply the yaml file to the K8s cluster.

$kubectl apply-f mydeploy.yamlworkloaddefinition.core.oam.dev/mydeploy created

Once the new capability kubectl apply is added to Kubernetes, there is no need to restart or update it. Users of KubeVela can immediately see a new capability appear and can be used:

$vela worklaodsAutomatically discover capabilities successfully ✅ Add (1) Update (0) Delete (0) TYPE CATEGORY DESCRIPTION+mydeploy workload description not definedNAME DESCRIPTIONmydeploy description not defined

It is used in Appfile as follows:

Name: my-extend-appservices: mysvc: type: mydeploy image: crccheck/hello-world name: mysvc

Execute vela up to get this up and running:

$vela up-f docs/examples/blog-extension/my-extend-app.yamlParsing vela appfile... Loading templates... Rendering configs for service (mysvc)... Writing deploy config to (.vela / deploy.yaml) Applying deploy configs... Checking if app has been deployed...App has not been deployed, creating a new deployment... ✅ App has been deployed? Port forward: vela port-forward my-extend-app SSH: vela exec my-extend-app Logging: vela logs my-extend-app App status: vela status my-extend-app Service status: vela status my-extend-app-- svc mysvc

Let's take a look at the status of the application, which is running normally (HEALTHY Ready: 1Accord 1):

Advanced usage in the template of $vela status my-extend-appAbout: Name: my-extend-app Namespace: env-application Created at: 2020-12-15 16 my-extend-app Namespace 25.08233 + 0800 CST Updated at: 2020-12-15 16 Paradise 25.08233 + 0800 CSTServices:-Name: mysvc Type: mydeploy HEALTHY Ready: 1/1Definition

Above we have experienced the whole process of extending KubeVela through template replacement, in addition, you may have some more complex requirements, such as conditional judgment, loops, complex types, etc., which require some advanced usage.

Structural parameters

If there are some complex parameter types in the template, including structures and multiple nested structures, you can use structure definitions.

Defines a structure type that contains 1 string member, 1 integer, and 1 structure member.

# Config: {name: string value: int other: {key: string value: string}}

Use this structure type in variables and use it as an array.

Parameter: {name: string image: string config: [... # Config]}

The same goal is also used in the form of variable references.

Output: {... Spec: {containers: [{name: parameter.name image: parameter.image env: parameter.config}]}...}

The writing in Appfile is written according to the structure defined by parameter.

Name: my-extend-appservices:mysvc: type: mydeploy image: crccheck/hello-world name: mysvc config:-name: a value: 1 other: key: mykey value: myvalue condition judgment

Sometimes whether certain parameters are added or not depends on certain conditions:

Parameter: {name: string image: string useENV: bool} output: {... Spec: {containers: [{name: parameter.name image: parameter.image if parameter.useENV = = true {env: [{name: "my-env", value: "my-value"}}]}.}.

In Appfile is to write the value.

Name: my-extend-appservices: mysvc: type: mydeploy image: crccheck/hello-world name: mysvc useENV: true can be defaulted

In some cases, the parameter may or may not exist, that is, it is not required. It is usually used in accordance with the condition. In the case where a field does not exist, the judgment condition is _ variable! = _ | _.

Parameter: {name: string image: string config?: [... # Config]} output: {... Spec: {containers: [{name: parameter.name image: parameter.image if parameter.config! = _ | _ {config: parameter.config}}]}.}

In this case, the config of Appfile is not required. If it is filled in, it will be rendered. If it is not filled, it will not be rendered.

Default value

If you want to set a default value for some parameters, you can use this method.

Parameter: {name: string image: * "nginx:v1" | string} output: {. Spec: {containers: [{name: parameter.name image: parameter.image}]}...}

At this point, Appfile does not need to write the parameter image, and defaults to "nginx:v1":

Name: my-extend-appservices: mysvc: type: mydeploy name: mysvc Loop parameter: {name: string image: string env: [string]: string} output: {spec: {containers: [{name: parameter.name image: parameter.image env: [for k V in parameter.env {name: k value: v},]}]}}

How to write in Appfile:

Name: my-extend-appservices: mysvc: type: mydeploy name: "mysvc" image: "nginx" env: env1: value1 env2: value2 array type circular parameter: {name:string image: string env: [. {name:string,value:string}]} output: {. Spec: {containers: [{name: parameter.name image: parameter.image env: [for _, v in parameter.env {name: v.name value: v.value},]}]}}

How to write in Appfile:

Name: my-extend-appservices: mysvc: type: mydeploy name: "mysvc" image: "nginx" env:-name: env1 value: value1-name: env2 value: value2KubeVela built-in context variable

You may have noticed that the name we defined in parameter is actually written twice in Appfile each time, once under services (each service is distinguished by name) and once in the specific name parameter. In fact, what is repeated here should not be written by the user again, so a built-in context is defined in KubeVela, which stores some general environment context information, such as application name, secret key, etc. There is no need to add an additional name parameter to use context directly in the template, KubeVela will be passed in automatically when you run the rendering template.

Parameter: {image: string} output: {... Annotation enhancements in spec: {containers: [{name: context.name image: parameter.image}]}...} KubeVela

KubeVela has also made some extensions to cuelang's comments to facilitate automatic documentation and use by CLI.

Parameter: {/ / + usage=Which image would you like to use for your service / / + short=i image: string / / + usage=Commands to run in the container cmd?: [. String].}

Where the comment that begins with + usgae becomes the description of the parameter, and the comment that begins with + short is followed by the abbreviation used in CLI.

The above is the editor for you to share how to give your K8s PaaS online a new function, if you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

  • How to install and use cgroup in ceph

    This article will explain in detail how to install and use cgroup in ceph. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article. Package installation

    © 2024 shulou.com SLNews company. All rights reserved.

    12
    Report