這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)KubeVela是如何將appfile轉(zhuǎn)換為K8s特定資源對(duì)象的,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十多年企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都成百上千家客戶提供網(wǎng)頁(yè)設(shè)計(jì)制作,網(wǎng)站開(kāi)發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營(yíng)銷(xiāo)型網(wǎng)站建設(shè),品牌網(wǎng)站制作,同時(shí)也為不同行業(yè)的客戶提供網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選創(chuàng)新互聯(lián)公司。
KubeVela 是一個(gè)簡(jiǎn)單易用又高度可擴(kuò)展的云原生應(yīng)用管理引擎,是基于 Kubernetes 及阿里云與微軟云共同發(fā)布的云原生應(yīng)用開(kāi)發(fā)模型 OAM 構(gòu)建。
KubeVela 基于 OAM 模型構(gòu)建了一套具體的實(shí)現(xiàn),通過(guò) Golang 編寫(xiě),可以端到端地為用戶構(gòu)建云原生應(yīng)用的平臺(tái),提供一個(gè)相對(duì)完整的解決方案。
下面主要目的是探索 KubeVela 如何將一個(gè) appfile 文件轉(zhuǎn)換為 K8s 中特定的資源對(duì)象。
該過(guò)程總的來(lái)說(shuō)分為兩個(gè)階段:
appfile 轉(zhuǎn)為 K8s 中的 application
application 轉(zhuǎn)換為對(duì)應(yīng)的 K8s 資源對(duì)象
# vela.yaml name: test services: nginx: type: webservice image: nginx env: - name: NAME value: kubevela # svc trait svc: type: NodePort ports: - port: 80 nodePort: 32017
利用 vela up 命令可以完成部署。
建議:在看 vela 命令行工具代碼之前,先去簡(jiǎn)單了解一下 cobra 框架。
// references/cli/up.go // NewUpCommand will create command for applying an AppFile func 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 函數(shù)中,通過(guò)調(diào)用 c.SetConfig() 完成 Kuberentes 配置信息 kubeconfig 的注入。
在 RunE 函數(shù)中:
首先,獲取 vela 的 env 變量,velaEnv.Namespace 對(duì)應(yīng) Kubernetes 的命名空間。
其次,獲取 Kubernetes 的客戶端,kubectl。
接著,利用 Kubernetes 客戶端和 vleaEnv 來(lái)構(gòu)建渲染 Appfile 需要的 AppfileOptions。
最后,調(diào)用 o.Run(filePath, velaEnv.Namespace, c)。
filePath: appfile 的路徑
velaEnv.Namespace:對(duì)應(yīng) K8s 的 namespace
c:K8s 客戶端
該函數(shù)需要三個(gè)參數(shù),其中 filePath 用于指定 appfile 的位置,velaEnv.Namespace 和 c 用來(lái)將渲染后的 Application 創(chuàng)建到指定命名空間。
起點(diǎn):appfile
終點(diǎn):applicatioin
路徑:appfile -> application (services -> component)
comp[workload, traits]
// references/appfile/api/appfile.go // AppFile defines the spec of KubeVela Appfile type 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 struct func 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 會(huì)將指定路徑的 yaml 文件讀取后,賦值給一個(gè) AppFile。
// references/appfile/api/appfile.go // LoadFromFile will read the file and load the AppFile struct func 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 中的數(shù)據(jù):
# vela.yaml name: test services: nginx: type: webservice image: nginx env: - name: NAME value: kubevela # svc trait svc: type: NodePort ports: - port: 80 nodePort: 32017
Name: test CreateTime: 0001-01-01 00:00:00 +0000 UTC UpdateTime: 0001-01-01 00:00:00 +0000 UTC Services: 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
// apis/core.oam.dev/application_types.go type 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 Application type 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 的聲明,結(jié)合 .vela/deploy.yaml(見(jiàn)下面代碼),可以看出,要將一個(gè) AppFile 渲染為 Application 主要就是將 AppFile 的 Services 轉(zhuǎn)化為 Application 的 Components。
# .vela/deploy.yaml apiVersion: core.oam.dev/v1alpha2 kind: Application metadata: creationTimestamp: null name: test namespace: default spec: 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: webservice status: {}
結(jié)合以上內(nèi)容可以看出,將 Appfile 轉(zhuǎn)化為 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 的轉(zhuǎn)化 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 轉(zhuǎn)化為 Application 代碼實(shí)現(xiàn)的位置。其中 comp, err := svc.RenderServiceToApplicationComponent(tm, serviceName) 完成 Service 到 Component 的轉(zhuǎn)化。
// 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 }
執(zhí)行 vela up 命令,渲染 appfile 為 Application,將數(shù)據(jù)寫(xiě)入到 .vela/deploy.yaml 中,并在 K8s 中創(chuàng)建。
起點(diǎn):Application
中點(diǎn):ApplicationConfiguration, Component
終點(diǎn):Deployment, Service
路徑:
application_controller
applicationconfiguration controller
【建議】> 了解一下內(nèi)容:> - client-to
controller-runtime
operator
# 獲取集群中的 Application $ kubectl get application NAMESPACE NAME AGE default test 24h
當(dāng) application controller 獲取到 Application 資源對(duì)象之后,會(huì)根據(jù)其內(nèi)容創(chuàng)建出對(duì)應(yīng)的 ApplicationConfiguration 和 Component。
# 獲取 ApplicationConfiguration 和 Component $ kubectl get ApplicationConfiguration,Component NAME AGE applicationconfiguration.core.oam.dev/test 24h NAME WORKLOAD-KIND AGE component.core.oam.dev/nginx Deployment 24h
ApplicationiConfiguration 中以名字的方式引入 Component:
獲取一個(gè) Application 資源對(duì)象。
將 Application 資源對(duì)象渲染為 ApplicationConfiguration 和 Component。
創(chuàng)建 ApplicationConfiguration 和 Component 資源對(duì)象。
// pkg/controller/core.oam.dev/v1alpha2/application/application_controller.go // Reconcile process app event func (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 轉(zhuǎn)換為 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. 在集群中創(chuàng)建 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) }
獲取 ApplicationConfiguration 資源對(duì)象。
循環(huán)遍歷,獲取每一個(gè) Component 并將 workload 和 trait 渲染為對(duì)應(yīng)的 K8s 資源對(duì)象。
創(chuàng)建對(duì)應(yīng)的 K8s 資源對(duì)象。
// 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 controller func (r *OAMApplicationReconciler) ACReconcile(ctx context.Context, ac *v1alpha2.ApplicationConfiguration, log logging.Logger) (result reconcile.Result, returnErr error) { ... // 2. 渲染 // 此處 workloads 包含所有Component對(duì)應(yīng)的的 workload 和 tratis 的 k8s 資源對(duì)象 workloads, depStatus, err := r.components.Render(ctx, ac) ... applyOpts := []apply.ApplyOption{apply.MustBeControllableBy(ac.GetUID()), applyOnceOnly(ac, r.applyOnceOnlyMode, log)} // 3. 創(chuàng)建 workload 和 traits 對(duì)應(yīng)的 k8s 資源對(duì)象 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 }
當(dāng) vela up 將一個(gè) AppFile 渲染為一個(gè) Application 后,后續(xù)的流程由 application controller 和 applicationconfiguration controller 完成。
上述就是小編為大家分享的KubeVela是如何將appfile轉(zhuǎn)換為K8s特定資源對(duì)象的了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
本文標(biāo)題:KubeVela是如何將appfile轉(zhuǎn)換為K8s特定資源對(duì)象的
分享URL:http://muchs.cn/article44/jehgee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、用戶體驗(yàn)、網(wǎng)站導(dǎo)航、面包屑導(dǎo)航、網(wǎng)站收錄、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)