日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何在 20 分钟内给你的 K8s PaaS 上线一个新功能?

發布時間:2025/3/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在 20 分钟内给你的 K8s PaaS 上线一个新功能? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


作者 | 孫健波(天元)
來源|阿里巴巴云原生公眾號

上個月,KubeVela 正式發布了, 作為一款簡單易用且高度可擴展的應用管理平臺與核心引擎,可以說是廣大平臺工程師用來構建自己的云原生 PaaS 的神兵利器。 那么本文就以一個實際的例子,講解一下如何在 20 分鐘內,為你基于 KubeVela 的 PaaS “上線“一個新能力。

在正式開始本文檔的教程之前,請確保你本地已經正確安裝了 KubeVela 及其依賴的 K8s 環境。

KubeVela 擴展的基本結構

KubeVela 的基本架構如圖所示:

簡單來說,KubeVela 通過添加 Workload TypeTrait 來為用戶擴展能力,平臺的服務提供方通過 Definition 文件注冊和擴展,向上通過 Appfile 透出擴展的功能。官方文檔中也分別給出了基本的編寫流程,其中 2 個是 Workload 的擴展例子,一個是 Trait 的擴展例子:

  • OpenFaaS 為例的 Workload Type 擴展
  • 云資源 RDS 為例的 Workload Type 擴展
  • KubeWatch 為例的 Trait 擴展

我們以一個內置的 WorkloadDefinition 為例來介紹一下 Definition 文件的基本結構:

apiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata:name: webserviceannotations: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.appsextension: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.nameimage: parameter.imageif 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.cpurequests:cpu: parameter.cpu}}}]}}}}parameter: {// +usage=Which image would you like to use for your service// +short=iimage: string// +usage=Commands to run in the containercmd?: [...string]// +usage=Which port do you want customer traffic sent to// +short=pport: *80 | int// +usage=Define arguments by using environment variablesenv?: [...{// +usage=Environment variable namename: string// +usage=The value of the environment variablevalue?: string// +usage=Specifies a source the value of this var should come fromvalueFrom?: {// +usage=Selects a key of a secret in the pod's namespacesecretKeyRef: {// +usage=The name of the secret in the pod's namespace to select fromname: string// +usage=The key of the secret to select from. Must be a valid secret keykey: string}}}]// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)cpu?: string}

乍一看挺長的,好像很復雜,但是不要著急,其實細看之下它分為兩部分:

  • 不含擴展字段的 Definition 注冊部分
  • 供 Appfile 使用的擴展模板(CUE Template)部分

我們拆開來慢慢介紹,其實學起來很簡單。

不含擴展字段的 Definition 注冊部分

apiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata:name: webserviceannotations: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

這一部分滿打滿算 11 行,其中有 3 行是在介紹 webservice 的功能,5行是固定的格式。只有 2 行是有特定信息:

definitionRef:name: deployments.apps

這兩行的意思代表了這個 Definition 背后用的 CRD 名稱是什么,其格式是 <resources>.<api-group>。了解 K8s 的同學應該知道 K8s 中比較常用的是通過 api-group, version 和 kind 定位資源,而 kind 在 K8s restful API 中對應的是 resources。以大家熟悉 Deployment 和 ingress 為例,它的對應關系如下:

![image.png](https://img-blog.csdnimg.cn/img_convert/bf72f5ef3c83bc67071d3201413a688f.png#align=left&display=inline&height=76&margin=[object Object]&name=image.png&originHeight=133&originWidth=1296&size=10962&status=done&style=none&width=744)

這里補充一個小知識,為什么有了 kind 還要加個 resources 的概念呢? 因為一個 CRD 除了 kind 本身還有一些像 status,replica 這樣的字段希望跟 spec 本身解耦開來在 restful API 中單獨更新, 所以 resources 除了 kind 對應的那一個,還會有一些額外的 resources,如 Deployment 的 status 表示為 deployments/status。

所以相信聰明的你已經明白了不含 extension 的情況下,Definition 應該怎么寫了,最簡單的就是根據 K8s 的資源組合方式拼接一下,只要填下面三個尖括號的空格就可以了。

apiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata:name: <這里寫名稱> spec:definitionRef:name: <這里寫resources>.<這里寫api-group>

針對運維特征注冊(TraitDefinition)也是這樣。

apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata:name: <這里寫名稱> spec:definitionRef:name: <這里寫resources>.<這里寫api-group>

所以把 Ingress 作為 KubeVela 的擴展寫進去就是:

apiVersion: core.oam.dev/v1alpha2 kind: TraitDefinition metadata:name: ingress spec:definitionRef:name: ingresses.networking.k8s.io

除此之外,TraitDefinition 中還增加了一些其他功能模型層功能,如:

  • appliesToWorkloads: 表示這個 trait 可以作用于哪些 Workload 類型。
  • conflictWith: 表示這個 trait 和哪些其他類型的 trait 有沖突。
  • workloadRefPath: 表示這個 trait 包含的 workload 字段是哪個,KubeVela 在生成 trait 對象時會自動填充。 …

這些功能都是可選的,本文中不涉及使用,在后續的其他文章中我們再給大家詳細介紹。

所以到這里,相信你已經掌握了一個不含 extensions 的基本擴展模式,而剩下部分就是圍繞 CUE 的抽象模板。

供 Appfile 使用的擴展模板(CUE Template)部分

對 CUE 本身有興趣的同學可以參考這篇 CUE 基礎入門 多做一些了解,限于篇幅本文對 CUE 本身不詳細展開。

大家知道 KubeVela 的 Appfile 寫起來很簡潔,但是 K8s 的對象是一個相對比較復雜的 YAML,而為了保持簡潔的同時又不失可擴展性,KubeVela 提供了一個從復雜到簡潔的橋梁。 這就是 Definition 中 CUE Template 的作用。

CUE 格式模板

讓我們先來看一個 Deployment 的 YAML 文件,如下所示,其中很多內容都是固定的框架(模板部分),真正需要用戶填的內容其實就少量的幾個字段(參數部分)。

apiVersion: apps/v1 kind: Deployment meadata:name: mytest spec:template:spec:containers:- name: mytestenv:- name: avalue: bimage: nginx:v1metadata:labels:app.oam.dev/component: mytestselector:matchLabels:app.oam.dev/component: mytest

在 KubeVela 中,Definition 文件的固定格式就是分為 output 和 parameter 兩部分。其中output中的內容就是“模板部分”,而 parameter 就是參數部分。

那我們來把上面的 Deployment YAML 改寫成 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"}]}]}}} }

這個格式跟 json 很像,事實上這個是 CUE 的格式,而 CUE 本身就是一個 json 的超集。也就是說,CUE的格式在滿足 JSON 規則的基礎上,增加了一些簡便規則, 使其更易讀易用:

  • C 語言的注釋風格。
  • 表示字段名稱的雙引號在沒有特殊符號的情況下可以缺省。
  • 字段值結尾的逗號可以缺省,在字段最后的逗號寫了也不會出錯。
  • 最外層的大括號可以省略。

CUE 格式的模板參數–變量引用

編寫好了模板部分,讓我們來構建參數部分,而這個參數其實就是變量的引用。

parameter: {name: stringimage: 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.nameimage: parameter.image}]}}} }

如上面的這個例子所示,KubeVela 中的模板參數就是通過 parameter 這個部分來完成的,而 parameter 本質上就是作為引用,替換掉了 output 中的某些字段。

完整的 Definition 以及在 Appfile 使用

事實上,經過上面兩部分的組合,我們已經可以寫出一個完整的 Definition 文件:

apiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata:name: mydeploy spec:definitionRef:name: deployments.appsextension:template: |parameter: {name: stringimage: 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.nameimage: parameter.image}]}}}}

為了方便調試,一般情況下可以預先分為兩個文件,一部分放前面的 yaml 部分,假設命名為 def.yaml 如:

apiVersion: core.oam.dev/v1alpha2 kind: WorkloadDefinition metadata:name: mydeploy spec:definitionRef:name: deployments.appsextension:template: |

另一個則放 cue 文件,假設命名為 def.cue :

parameter: {name: stringimage: 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.nameimage: parameter.image}]}}} }

先對 def.cue 做一個格式化,格式化的同時 cue 工具本身會做一些校驗,也可以更深入的通過 cue 命令做調試:

cue fmt def.cue

調試完成后,可以通過腳本把這個 yaml 組裝:

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

再把這個 yaml 文件 apply 到 K8s 集群中。

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

一旦新能力 kubectl apply 到了 Kubernetes 中,不用重啟,也不用更新,KubeVela 的用戶可以立刻看到一個新的能力出現并且可以使用了:

$ vela worklaods Automatically discover capabilities successfully ? Add(1) Update(0) Delete(0)TYPE CATEGORY DESCRIPTION +mydeploy workload description not definedNAME DESCRIPTION mydeploy description not defined

在 Appfile 中使用方式如下:

name: my-extend-app services:mysvc:type: mydeployimage: crccheck/hello-worldname: mysvc

執行 vela up 就能把這個運行起來了:

$ vela up -f docs/examples/blog-extension/my-extend-app.yaml Parsing 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-appSSH: vela exec my-extend-appLogging: vela logs my-extend-appApp status: vela status my-extend-appService status: vela status my-extend-app --svc mysvc

我們來查看一下應用的狀態,已經正常運行起來了(HEALTHY Ready: 1/1):

$ vela status my-extend-app About:Name: my-extend-appNamespace: env-applicationCreated at: 2020-12-15 16:32:25.08233 +0800 CSTUpdated at: 2020-12-15 16:32:25.08233 +0800 CSTServices:- Name: mysvcType: mydeployHEALTHY Ready: 1/1

Definition 模板中的高級用法

上面我們已經通過模板替換這個最基本的功能體驗了擴展 KubeVela 的全過程,除此之外,可能你還有一些比較復雜的需求,如條件判斷,循環,復雜類型等,需要一些高級的用法。

結構體參數

如果模板中有一些參數類型比較復雜,包含結構體和嵌套的多個結構體,就可以使用結構體定義。

  • 定義一個結構體類型,包含 1 個字符串成員、1 個整型和 1 個結構體成員。
  • #Config: {name: stringvalue: intother: {key: stringvalue: string} }
  • 在變量中使用這個結構體類型,并作為數組使用。
  • parameter: {name: stringimage: stringconfig: [...#Config] }
  • 同樣的目標中也是以變量引用的方式使用。
  • output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageenv: parameter.config}]}... }
  • Appfile 中的寫法就是按照 parameter 定義的結構編寫。
  • name: my-extend-app services: mysvc:type: mydeployimage: crccheck/hello-worldname: mysvcconfig:- name: avalue: 1other:key: mykeyvalue: myvalue

    條件判斷

    有時候某些參數加還是不加取決于某個條件:

    parameter: {name: stringimage: stringuseENV: bool } output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageif parameter.useENV == true {env: [{name: "my-env", value: "my-value"}]}}]}... }

    在 Appfile 就是寫值。

    name: my-extend-app services:mysvc:type: mydeployimage: crccheck/hello-worldname: mysvcuseENV: true

    可缺省參數

    有些情況下參數可能存在也可能不存在,即非必填,這個時候一般要配合條件判斷使用,對于某個字段不存在的情況,判斷條件是是 _variable != _|_。

    parameter: {name: stringimage: stringconfig?: [...#Config] } output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageif parameter.config != _|_ {config: parameter.config}}]}... }

    這種情況下 Appfile 的 config 就非必填了,填了就渲染,沒填就不渲染。

    默認值

    對于某些參數如果希望設置一個默認值,可以采用這個寫法。

    parameter: {name: stringimage: *"nginx:v1" | string } output: {...spec: {containers: [{name: parameter.nameimage: parameter.image}]}... }

    這個時候 Appfile 就可以不寫 image 這個參數,默認使用 “nginx:v1”:

    name: my-extend-app services:mysvc:type: mydeployname: mysvc

    循環

    Map 類型的循環

    parameter: {name: stringimage: stringenv: [string]: string } output: {spec: {containers: [{name: parameter.nameimage: parameter.imageenv: [for k, v in parameter.env {name: kvalue: v},]}]} }

    Appfile 中的寫法:

    name: my-extend-app services:mysvc:type: mydeployname: "mysvc"image: "nginx"env:env1: value1env2: value2

    數組類型的循環

    parameter: {name: stringimage: stringenv: [...{name:string,value:string}] } output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageenv: [for _, v in parameter.env {name: v.namevalue: v.value},]}]} }

    Appfile 中的寫法:

    name: my-extend-app services:mysvc:type: mydeployname: "mysvc"image: "nginx"env:- name: env1value: value1- name: env2value: value2

    KubeVela 內置的 context 變量

    大家可能也注意到了,我們在 parameter 中定義的 name 每次在 Appfile中 實際上寫了兩次,一次是在 services 下面(每個service都以名稱區分), 另一次則是在具體的name參數里面。事實上這里重復的不應該由用戶再寫一遍,所以 KubeVela 中還定義了一個內置的 context,里面存放了一些通用的環境上下文信息,如應用名稱、秘鑰等。 直接在模板中使用 context 就不需要額外增加一個 name 參數了, KubeVela 在運行渲染模板的過程中會自動傳入。

    parameter: {image: string } output: {...spec: {containers: [{name: context.nameimage: parameter.image}]}... }

    KubeVela 中的注釋增強

    KubeVela 還對 cuelang 的注釋做了一些擴展,方便自動生成文檔以及被 CLI 使用。

    parameter: {// +usage=Which image would you like to use for your service// +short=iimage: string// +usage=Commands to run in the containercmd?: [...string]...}

    其中,+usgae 開頭的注釋會變成參數的說明,+short 開頭的注釋后面則是在 CLI 中使用的縮寫。

    總結

    本文通過實際的案例和詳細的講述,為你介紹了在 KubeVela 中新增一個能力的詳細過程與原理,以及能力模板的編寫方法。

    這里你可能還有個疑問,平臺管理員這樣添加了一個新能力后,平臺的用戶又該怎么能知道這個能力怎么使用呢?其實,在 KubeVela 中,它不僅能方便的添加新能力,它還能自動為“能力”生成 Markdown 格式的使用文檔! 不信,你可以看下 KubeVela 本身的官方網站,所有在 References/Capabilities 目錄下能力使用說明文檔(比如這個),全都是根據每個能力的模板自動生成的哦。 最后,歡迎大家寫一些有趣的擴展功能,提交到 KubeVela 的社區倉庫中來。

    如果你有任何疑問,歡迎釘釘搜索群號:23310022 加入交流群。

    總結

    以上是生活随笔為你收集整理的如何在 20 分钟内给你的 K8s PaaS 上线一个新功能?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 巨乳中文字幕 | 处破痛哭a√18成年片免费 | 亚洲午夜小视频 | 日本成人网址 | 国产欧美一区二区三区沐欲 | 久久精品99国产 | 久久精品无码人妻 | 中文字幕在线看片 | 狠狠干干干| 精品一区二区三区欧美 | 九九九热精品 | 中文字幕22页 | 无码国产色欲xxxx视频 | 国产又粗又猛又爽又黄的网站 | 久久澡 | av亚州| 免费毛片基地 | 亚洲最大成人在线 | 亚洲无打码| 久久国产亚洲精品无码 | av电影在线播放 | 免费毛片看片 | 欧美一区二区三区视频在线 | 99热这里只有精品66 | 国产麻豆xxxvideo实拍 | 欧美激情精品久久久久久变态 | 久久香蕉综合 | 韩国三级国产 | 夜夜天天干| 日韩在线精品强乱中文字幕 | 中日韩精品在线 | 国产成人无码一区二区在线观看 | 精品视频久久久久久久 | 岳奶大又白下面又肥又黑水多 | 欧美一级淫| 黄色三级视屏 | 狠狠躁夜夜 | 天天干天天操天天插 | 国产精品激情偷乱一区二区∴ | 久久免费在线观看 | 国产精品毛片一区视频播 | 理想之城连续剧40集免费播放 | 欧美福利电影 | 久久精品无码一区 | 欧美裸体视频 | 久久久久久久成人 | 97超碰中文 | 中文字幕美女 | 欧美一级xxx | 男女插鸡视频 | 人妻av一区二区三区 | 日日狠狠久久 | 欧美精品黑人 | 色婷婷狠狠操 | 天天干天天舔 | 午夜一级视频 | 一级绝黄 | 三级免费黄录像 | 欧美一区二区在线视频 | 欧美一级在线免费 | 黑鬼大战白妞高潮喷白浆 | 海角国产乱辈乱精品视频 | 色中文在线 | 在线天堂v | 91成年人网站 | 欧美老司机 | 麻豆成人在线 | 欧美性生交大片免费看app麻豆 | 快播久久 | 蜜臀av性久久久久蜜臀av麻豆 | 亚洲理论片在线观看 | 日韩视频免费 | 亚洲经典在线 | 亚洲欧美乱日韩乱国产 | 怡红院综合网 | 欧美真人性野外做爰 | 在线免费观看毛片 | 嫩草视频在线观看视频 | 1级性生活片| 国产视频精品久久 | 亚洲欧洲在线观看 | 国产做受入口竹菊 | 亚洲无吗av | 日本午夜视频 | 黄色片网站在线播放 | 午夜91 | 国产乱人视频 | 欧美巨乳在线观看 | 国产91精| 中文字幕影片免费在线观看 | 日本www| 国产欧美日韩精品区一区二污污污 | 日本色片网站 | 少妇视频在线观看 | 久久精品国产久精国产 | 久久视奸 | 乳女教师の诱惑julia | 成人p站在线观看 | 干操网 |