K8s PaaSに20分で新しい機能を追加するにはどうすればよいですか?

ヘッドpicture.png
著者| Sun Jianbo(Tian Yuan)
出典| AlibabaCloudネイティブ公式アカウント

先月、KubeVelaは、シンプルで使いやすく、拡張性の高いアプリケーション管理プラットフォームおよびコアエンジンとして正式にリリースされました。これは、プラットフォームエンジニアが独自のクラウドネイティブPaaSを構築するための魔法の武器と言えます。次に、この記事では、実用的な例を使用して、KubeVelaPaaSに基づく新しい機能を20分以内に「実行」する方法を説明します。

このドキュメントのチュートリアルを開始する前に、KubeVelaとそれに依存するK8s環境が正しくインストールされていることを確認してください

KubeVela拡張機能の基本構造

KubeVelaの基本構造を図に示します。

1.png

簡単に言うと、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を知りリソースversionkind見つけkind、K8s対応するRestfulAPIはresourcesです。おなじみのDeploymentingressたとえば、その対応は次のとおりです。

image.png

ここに少し知識がありますが、種類があるのになぜリソースの概念を追加する必要があるのですか?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 

おすすめ

転載: blog.51cto.com/13778063/2571763