著者| Sun Jianbo(Tian Yuan)
出典| AlibabaCloudネイティブ公式アカウント
先月、KubeVelaは、シンプルで使いやすく、拡張性の高いアプリケーション管理プラットフォームおよびコアエンジンとして正式にリリースされました。これは、プラットフォームエンジニアが独自のクラウドネイティブPaaSを構築するための魔法の武器と言えます。次に、この記事では、実用的な例を使用して、KubeVelaPaaSに基づく新しい機能を20分以内に「実行」する方法を説明します。
このドキュメントのチュートリアルを開始する前に、KubeVelaとそれに依存するK8s環境が正しくインストールされていることを確認してください。
KubeVela拡張機能の基本構造
KubeVelaの基本構造を図に示します。
簡単に言うと、KubeVelaは、ワークロードタイプと特性を追加することにより、ユーザーの機能を拡張します。プラットフォームのサービスプロバイダーは、定義ファイルを介して登録および拡張し、Appfileを介して拡張された機能を公開します。基本的な書き込みプロセスは公式ドキュメントにも記載されており、そのうちの2つはワークロードの拡張例であり、1つは特性の拡張例です。
定義ファイルの基本構造を紹介する例として、組み込みのWorkloadDefinitionを取り上げます。
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
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
}
一見、かなり長く見え、非常に複雑に見えますが、心配しないでください。実際には2つの部分に分かれています。
- 拡張フィールドのない定義登録部分
- AppfileのCUEテンプレートセクション
分解してゆっくりと紹介していきましょうが、実はとても習得しやすいです。
拡張フィールドのない定義登録部分
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
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
この部分のManDaManSuan行11、行3はwebservice
関数で導入され、行5は固定形式です。特定の情報があるのは2行だけです。
definitionRef:
name: deployments.apps
これらの2行の意味は、この定義の背後で使用されているCRD名を表しており、その形式は<resources>.<api-group>
です。K8sを学ぶ学生はapi-group
、によってより一般的に使用されるK8sを知り、リソースversion
をkind
見つけkind
、K8sで対応するRestfulAPIはresources
です。おなじみのDeployment
、ingress
たとえば、その対応は次のとおりです。
ここに少し知識がありますが、種類があるのになぜリソースの概念を追加する必要があるのですか?CRDには、種類自体に加えてステータスやレプリカなどのフィールドがあり、仕様自体から切り離して、残りのAPIで個別に更新することを望んでいるため、リソースに対応する種類に加えて、展開などの追加のリソースがいくつかあります。ステータスはとして表され
deployments/status
ます。
ですから、あなたは定義を拡張せずにどのように書くべきかを理解するのに十分賢いと思います。最も簡単な方法は、K8sリソースの組み合わせ方法に従ってそれを接続することです。次の3つの山括弧内のスペースに入力するだけです。
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
:この特性が作用できるワークロードタイプを示します。conflictWith
:この特性が他のタイプの特性と競合することを示します。workloadRefPath
:この特性に含まれるワークロードフィールドを示します。KubeVelaは、特性オブジェクトの生成時に自動的に入力します。..。
これらの機能はオプションであり、この記事には含まれていません。他の後続の記事で詳細に紹介します。
したがって、ここでは、拡張機能のない基本的な拡張機能モードをマスターしたと思います。残りは、CUEに関する抽象的なテンプレートです。
AppfileのCUEテンプレートセクション
CUE自体に興味のある学生は、このCUEの基本の概要を参照して、理解を深めることができます。スペースの制限により、この記事ではCUE自体について詳しく説明しません。
KubeVelaのAppfileは非常に簡潔に記述できることは誰もが知っていますが、K8sのオブジェクトは比較的複雑なYAMLです。スケーラビリティを失うことなく簡潔に保つために、KubeVelaは複雑さから単純さへの架け橋を提供します。これは、定義におけるCUEテンプレートの役割です。
CUEフォーマットテンプレート
最初にデプロイメントYAMLファイルを見てみましょう。以下に示すように、コンテンツの多くは固定フレーム(テンプレート部分)であり、ユーザーが実際に入力する必要のあるコンテンツは実際にはいくつかのフィールド(パラメーター部分)です。
apiVersion: apps/v1
kind: Deployment
meadata:
name: mytest
spec:
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
KubeVelaでは、固定フォーマットの定義ファイルが2つの部分に分かれoutput
ていparameter
ます。どこoutput
内容は、「テンプレートの部」であり、parameter
引数の一部です。
次に、上記の展開YAMLを定義のテンプレートの形式に書き直してみましょう。
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: 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
}]
}}}
}
上記の例に示されているように、テンプレートパラメータKubeVelaはparameter
このセクションで実行さparameter
れますが、基本的には参照として、output
特定のフィールドを置き換えます。
完全な定義とAppfileでの使用
実際、上記の2つの部分を組み合わせた後、完全な定義ファイルを作成できます。
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: mydeploy
spec:
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
}]
}}}
}
デバッグを容易にするために、一般に、それは以前に2つのファイルに分割される場合があり、排出部分yamlの前部は次のように名前が付けられdef.yaml
ていると想定されます。
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: mydeploy
spec:
definitionRef:
name: deployments.apps
extension:
template: |
もう1つは、名前が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
}]
}}}
}
最初にdef.cue
フォーマットされたフォーマットを作成しますが、キューツール自体がいくつかのチェックを行いますが、デバッグキューコマンドを作成するためにさらに詳細にすることもできます。
cue fmt def.cue
デバッグ後、スクリプトを使用してこのyamlをアセンブルできます。
./hack/vela-templates/mergedef.sh def.yaml def.cue > mydeploy.yaml
次に、このyamlファイルを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 defined
NAME DESCRIPTION
mydeploy description not defined
Appfileでは次のように使用されます。
name: my-extend-app
services:
mysvc:
type: mydeploy
image: crccheck/hello-world
name: 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