千家信息网

KubeVela是如何将appfile转换为K8s特定资源对象的

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这期内容当中小编将会给大家带来有关KubeVela是如何将appfile转换为K8s特定资源对象的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。KubeVela 是
千家信息网最后更新 2026年10月31日KubeVela是如何将appfile转换为K8s特定资源对象的

这期内容当中小编将会给大家带来有关KubeVela是如何将appfile转换为K8s特定资源对象的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

KubeVela 是一个简单易用又高度可扩展的云原生应用管理引擎,是基于 Kubernetes 及阿里云与微软云共同发布的云原生应用开发模型 OAM 构建。

KubeVela 基于 OAM 模型构建了一套具体的实现,通过 Golang 编写,可以端到端地为用户构建云原生应用的平台,提供一个相对完整的解决方案。

下面主要目的是探索 KubeVela 如何将一个 appfile 文件转换为 K8s 中特定的资源对象。

该过程总的来说分为两个阶段:

  1. appfile 转为 K8s 中的 application

  2. application 转换为对应的 K8s 资源对象

# vela.yamlname: testservices:  nginx:    type: webservice    image: nginx    env:    - name: NAME      value: kubevela    # svc trait    svc:      type: NodePort      ports:      - port: 80        nodePort: 32017

利用 vela up 命令可以完成部署。

vela up 命令

建议:在看 vela 命令行工具代码之前,先去简单了解一下 cobra 框架。

// references/cli/up.go// NewUpCommand will create command for applying an AppFilefunc NewUpCommand(c types.Args, ioStream cmdutil.IOStreams) *cobra.Command {  cmd := &cobra.Command{    Use:                   "up",    DisableFlagsInUseLine: true,    Short:                 "Apply an appfile",    Long:                  "Apply an appfile",    Annotations: map[string]string{      types.TagCommandType: types.TypeStart,    },    PersistentPreRunE: func(cmd *cobra.Command, args []string) error {      return c.SetConfig()    },    RunE: func(cmd *cobra.Command, args []string) error {      velaEnv, err := GetEnv(cmd)      if err != nil {        return err      }      kubecli, err := c.GetClient()      if err != nil {        return err      }      o := &common.AppfileOptions{        Kubecli: kubecli,        IO:      ioStream,        Env:     velaEnv,      }      filePath, err := cmd.Flags().GetString(appFilePath)      if err != nil {        return err      }      return o.Run(filePath, velaEnv.Namespace, c)    },  }  cmd.SetOut(ioStream.Out)  cmd.Flags().StringP(appFilePath, "f", "", "specify file path for appfile")  return cmd}

上面源码展示的是 vela up 命令的入口。

在 PresistentPreRunE 函数中,通过调用 c.SetConfig() 完成 Kuberentes 配置信息 kubeconfig 的注入。

在 RunE 函数中:

  • 首先,获取 vela 的 env 变量,velaEnv.Namespace 对应 Kubernetes 的命名空间。

  • 其次,获取 Kubernetes 的客户端,kubectl。

  • 接着,利用 Kubernetes 客户端和 vleaEnv 来构建渲染 Appfile 需要的 AppfileOptions。

  • 最后,调用 o.Run(filePath, velaEnv.Namespace, c)。

    • filePath: appfile 的路径

    • velaEnv.Namespace:对应 K8s 的 namespace

    • c:K8s 客户端

    • 该函数需要三个参数,其中 filePath 用于指定 appfile 的位置,velaEnv.Namespace 和 c 用来将渲染后的 Application 创建到指定命名空间。

如何将一个 appfile 转为 Kubernetes 中的 Application

  • 起点:appfile

  • 终点:applicatioin

  • 路径:appfile -> application (services -> component)

    • comp[workload, traits]

1. 起点:AppFile

// references/appfile/api/appfile.go// AppFile defines the spec of KubeVela Appfiletype AppFile struct {  Name       string             `json:"name"`  CreateTime time.Time          `json:"createTime,omitempty"`  UpdateTime time.Time          `json:"updateTime,omitempty"`  Services   map[string]Service `json:"services"`  Secrets    map[string]string  `json:"secrets,omitempty"`  configGetter config.Store  initialized  bool}// NewAppFile init an empty AppFile structfunc NewAppFile() *AppFile {  return &AppFile{    Services:     make(map[string]Service),    Secrets:      make(map[string]string),    configGetter: &config.Local{},  }}
// references/appfile/api/service.go// Service defines the service spec for AppFile, it will contain all related information including OAM component, traits, source to image, etc...type Service map[string]interface{}

上面两段代码是 AppFile 在客户端的声明,vela 会将指定路径的 yaml 文件读取后,赋值给一个 AppFile。

// references/appfile/api/appfile.go// LoadFromFile will read the file and load the AppFile structfunc LoadFromFile(filename string) (*AppFile, error) {  b, err := ioutil.ReadFile(filepath.Clean(filename))  if err != nil {    return nil, err  }  af := NewAppFile()  // Add JSON format appfile support  ext := filepath.Ext(filename)  switch ext {  case ".yaml", ".yml":    err = yaml.Unmarshal(b, af)  case ".json":    af, err = JSONToYaml(b, af)  default:    if json.Valid(b) {      af, err = JSONToYaml(b, af)    } else {      err = yaml.Unmarshal(b, af)    }  }  if err != nil {    return nil, err  }  return af, nil}

下面为读取 vela.yaml 文件后,加载到 AppFile 中的数据:

# vela.yamlname: testservices:  nginx:    type: webservice    image: nginx    env:    - name: NAME      value: kubevela    # svc trait    svc:      type: NodePort      ports:      - port: 80        nodePort: 32017
Name: testCreateTime: 0001-01-01 00:00:00 +0000 UTCUpdateTime: 0001-01-01 00:00:00 +0000 UTCServices: map[             nginx: map[               env: [map[name: NAME value: kubevela]]                image: nginx                svc: map[ports: [map[nodePort: 32017 port: 80]] type: NodePort]                type: webservice            ]          ]Secrets    map[]configGetter: 0x447abd0 initialized: false

2. 终点:application

// apis/core.oam.dev/application_types.gotype Application struct {  metav1.TypeMeta   `json:",inline"`  metav1.ObjectMeta `json:"metadata,omitempty"`  Spec   ApplicationSpec `json:"spec,omitempty"`  Status AppStatus       `json:"status,omitempty"`}// ApplicationSpec is the spec of Applicationtype ApplicationSpec struct {  Components []ApplicationComponent `json:"components"`  // TODO(wonderflow): we should have application level scopes supported here  // RolloutPlan is the details on how to rollout the resources  // The controller simply replace the old resources with the new one if there is no rollout plan involved  // +optional  RolloutPlan *v1alpha1.RolloutPlan `json:"rolloutPlan,omitempty"`}

上面代码,为 Application 的声明,结合 .vela/deploy.yaml(见下面代码),可以看出,要将一个 AppFile 渲染为 Application 主要就是将 AppFile 的 Services 转化为 Application 的 Components。

# .vela/deploy.yamlapiVersion: core.oam.dev/v1alpha2kind: Applicationmetadata:  creationTimestamp: null  name: test  namespace: defaultspec:  components:  - name: nginx    scopes:      healthscopes.core.oam.dev: test-default-health    settings:      env:      - name: NAME        value: kubevela      image: nginx    traits:    - name: svc      properties:        ports:        - nodePort: 32017          port: 80        type: NodePort    type: webservicestatus: {}

3. 路径:Services -> Components

结合以上内容可以看出,将 Appfile 转化为 Application 主要是将 Services 渲染为 Components。

// references/appfile/api/appfile.go// BuildOAMApplication renders Appfile into Application, Scopes and other K8s Resources.func (app *AppFile) BuildOAMApplication(env *types.EnvMeta, io cmdutil.IOStreams, tm template.Manager, silence bool) (*v1alpha2.Application, []oam.Object, error) {  ...  servApp := new(v1alpha2.Application)  servApp.SetNamespace(env.Namespace)  servApp.SetName(app.Name)  servApp.Spec.Components = []v1alpha2.ApplicationComponent{}  for serviceName, svc := range app.GetServices() {    ...    // 完成 Service 到 Component 的转化    comp, err := svc.RenderServiceToApplicationComponent(tm, serviceName)    if err != nil {      return nil, nil, err    }    servApp.Spec.Components = append(servApp.Spec.Components, comp)  }  servApp.SetGroupVersionKind(v1alpha2.SchemeGroupVersion.WithKind("Application"))  auxiliaryObjects = append(auxiliaryObjects, addDefaultHealthScopeToApplication(servApp))  return servApp, auxiliaryObjects, nil}

上面的代码是 vela 将 Appfile 转化为 Application 代码实现的位置。其中 comp, err := svc.RenderServiceToApplicationComponent(tm, serviceName) 完成 Service 到 Component 的转化。

// references/appfile/api/service.go// RenderServiceToApplicationComponent render all capabilities of a service to CUE values to KubeVela Application.func (s Service) RenderServiceToApplicationComponent(tm template.Manager, serviceName string) (v1alpha2.ApplicationComponent, error) {  // sort out configs by workload/trait  workloadKeys := map[string]interface{}{}  var traits []v1alpha2.ApplicationTrait  wtype := s.GetType()  comp := v1alpha2.ApplicationComponent{    Name:         serviceName,    WorkloadType: wtype,  }  for k, v := range s.GetApplicationConfig() {    // 判断是否为 trait    if tm.IsTrait(k) {      trait := v1alpha2.ApplicationTrait{        Name: k,      }      ....      // 如果是 triat 加入 traits 中      traits = append(traits, trait)      continue    }    workloadKeys[k] = v  }  // Handle workloadKeys to settings  settings := &runtime.RawExte nsion{}  pt, err := json.Marshal(workloadKeys)  if err != nil {    return comp, err  }  if err := settings.UnmarshalJSON(pt); err != nil {    return comp, err  }  comp.Settings = *settings  if len(traits) > 0 {    comp.Traits = traits  }  return comp, nil}

4. 总结

执行 vela up 命令,渲染 appfile 为 Application,将数据写入到 .vela/deploy.yaml 中,并在 K8s 中创建。

Application 是如何转换为对应 K8s 资源对象

  • 起点:Application

  • 中点:ApplicationConfiguration, Component

  • 终点:Deployment, Service

  • 路径:

    • application_controller

    • applicationconfiguration controller

【建议】> 了解一下内容:> - client-to

  • controller-runtime

  • operator

1. Application

# 获取集群中的 Application$ kubectl get applicationNAMESPACE   NAME   AGEdefault     test   24h

2. ApplicationConfiguration 和 Component

当 application controller 获取到 Application 资源对象之后,会根据其内容创建出对应的 ApplicationConfiguration 和 Component。

# 获取 ApplicationConfiguration 和 Component$ kubectl get ApplicationConfiguration,ComponentNAME                                         AGEapplicationconfiguration.core.oam.dev/test   24hNAME                           WORKLOAD-KIND   AGEcomponent.core.oam.dev/nginx   Deployment      24h

ApplicationiConfiguration 中以名字的方式引入 Component:

3. application controller

基本逻辑:
  • 获取一个 Application 资源对象。

  • 将 Application 资源对象渲染为 ApplicationConfiguration 和 Component。

  • 创建 ApplicationConfiguration 和 Component 资源对象。

代码:
// pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go// Reconcile process app eventfunc (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {  ctx := context.Background()  applog := r.Log.WithValues("application", req.NamespacedName)    // 1. 获取 Application  app := new(v1alpha2.Application)  if err := r.Get(ctx, client.ObjectKey{    Name:      req.Name,    Namespace: req.Namespace,  }, app); err != nil {    ...  }  ...  // 2. 将 Application 转换为 ApplicationConfiguration 和 Component  handler := &appHandler{r, app, applog}  ...  appParser := appfile.NewApplicationParser(r.Client, r.dm)  ...  appfile, err := appParser.GenerateAppFile(ctx, app.Name, app)  ...  ac, comps, err := appParser.GenerateApplicationConfiguration(appfile, app.Namespace)  ...    // 3. 在集群中创建 ApplicationConfiguration 和 Component   // apply appConfig & component to the cluster  if err := handler.apply(ctx, ac, comps); err != nil {    applog.Error(err, "[Handle apply]")    app.Status.SetConditions(errorCondition("Applied", err))    return handler.handleErr(err)  }  ...  return ctrl.Result{}, r.UpdateStatus(ctx, app)}

4. applicationconfiguration controller

基本逻辑:
  • 获取 ApplicationConfiguration 资源对象。

  • 循环遍历,获取每一个 Component 并将 workload 和 trait 渲染为对应的 K8s 资源对象。

  • 创建对应的 K8s 资源对象。

代码:
// pkg/controller/core.oam.dev/v1alpha2/applicationcinfiguratioin/applicationconfiguratioin.go// Reconcile an OAM ApplicationConfigurations by rendering and instantiating its// Components and Traits.func (r *OAMApplicationReconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) {  ...  ac := &v1alpha2.ApplicationConfiguration{}  // 1. 获取 ApplicationConfiguration  if err := r.client.Get(ctx, req.NamespacedName, ac); err != nil {    ...  }  return r.ACReconcile(ctx, ac, log)}// ACReconcile contains all the reconcile logic of an AC, it can be used by other controllerfunc (r *OAMApplicationReconciler) ACReconcile(ctx context.Context, ac *v1alpha2.ApplicationConfiguration,  log logging.Logger) (result reconcile.Result, returnErr error) {    ...  // 2. 渲染  // 此处 workloads 包含所有Component对应的的 workload 和 tratis 的 k8s 资源对象  workloads, depStatus, err := r.components.Render(ctx, ac)  ...    applyOpts := []apply.ApplyOption{apply.MustBeControllableBy(ac.GetUID()), applyOnceOnly(ac, r.applyOnceOnlyMode, log)}    // 3. 创建 workload 和 traits 对应的 k8s 资源对象  if err := r.workloads.Apply(ctx, ac.Status.Workloads, workloads, applyOpts...); err != nil {    ...  }    ...  // the defer function will do the final status update  return reconcile.Result{RequeueAfter: waitTime}, nil}

5. 总结

当 vela up 将一个 AppFile 渲染为一个 Application 后,后续的流程由 application controller 和 applicationconfiguration controller 完成。

上述就是小编为大家分享的KubeVela是如何将appfile转换为K8s特定资源对象的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

对象 资源 代码 内容 命令 路径 客户 函数 客户端 文件 终点 起点 应用 位置 就是 建议 数据 模型 空间 逻辑 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 华服互联网科技怎么样 互联网科技工作委员会毛军 腾讯阿里互联网科技 互联网科技英文 浩特互联网科技 互联网科技logo设计 互联网高科技企业 互联网科技宣传片 上海亿帐通互联网科技 互联网科技有限公司 翻译 新华互联网科技校企合作 顺网科技2021年互联网排名 华中科技有哪些互联网大佬 知域互联网科技有限公司大骗子 亳州好赞互联网科技有限公司 深圳市罗太互联网科技有限公司 上海同邻互联网科技有限公司规模 长沙易易互联网科技有限公司 黑龙江互联网科技公司 科技发展第三阶段互联网时代 美国互联网黑科技 互联网科技大会 互联网 科技服务平台 滨湖区互联网智能科技产品供应 世界互联网科技公司市值排名 智腾互联网科技有限公司 华夏互联网科技业 互联网科技和信息 每天都有哪些好的互联网科技 广东工业互联网大赛深圳学泰科技
0