Kubernetes コンポーネントを Cloud Assembly クラウド テンプレートに追加するときに、クラスタを追加するか、ユーザーがさまざまな構成で名前空間を作成できるようにするかを選択できます。通常、この選択は、アクセス コントロールの要件、Kubernetes コンポーネントの構成方法、および展開の要件によって異なります。

Cloud Assembly のクラウド テンプレートに Kubernetes コンポーネントを追加するには、[デザイン] > [クラウド テンプレート] の順に選択し、[新規] をクリックし、左側のメニューで Kubernetes オプションを検索して展開します。次に、クラスタまたは KBS 名前空間のいずれかをキャンバスにドラッグすることで選択を行います。

プロジェクトに関連付けられた Kubernetes クラスタをクラウド テンプレートに追加する方法は、有効なユーザーが Kubernetes リソースを使用できるようにするための最も効率的な方法です。他の Cloud Assembly リソースと同様に、クラスタでタグを使用して、展開する場所を制御できます。クラスタ展開の割り当てフェーズでは、タグを使用してゾーンと VMware Tanzu Kubernetes Grid Integrated Edition (TKGI) プランを選択できます。

この方法でクラスタを追加すると、有効なすべてのユーザーが自動的にクラスタを使用できるようになります。

クラウド テンプレートの例

最初のクラウド テンプレートの例は、タグ付けによって制御される単純な Kubernetes 展開のテンプレートを示しています。Kubernetes ゾーンは、[新しい Kubernetes ゾーン] 画面上で構成され、2 つの展開プランを使用して作成されています。この例では、placement:tag というタグがゾーンの機能として追加され、クラウド テンプレートの同様な制約との照合に使用されています。複数のゾーンがこのタグを使用して構成されている場合、優先順位の番号が最も小さいゾーンが選択されます。

formatVersion: 1
inputs: {}
resources:
  Cluster_provisioned_from_tag:
    type: Cloud.K8S.Cluster
    properties:
      hostname: 109.129.209.125
      constraints:
	-tag: 'placement tag'
      port: 7003
      workers: 1
      connectBy: hostname 

2 番目のクラウド テンプレートの例では、ユーザーが展開を申請するときに目的のクラスタのホスト名を入力できるように、$(input.hostname) という変数を使用してテンプレートを設定する方法を示します。また、タグを使用して、クラスタ展開のリソース割り当てフェーズ中に、ゾーンと TKGI プランを選択することもできます。

formatVersion: 1
inputs:
  hostname:
    type: string
    title: Cluster hostname
resources:
  Cloud_K8S_Cluster_1:
    type: Cloud.K8S.Cluster
    properties:
      hostname: ${input.hostname}
      port: 8443
      connectBy: hostname
      workers: 1

名前空間を使用してクラスタ使用量を管理する場合は、クラウド テンプレートに name: ${input.name} という変数を設定できます。これは、展開の申請時にユーザーが入力する名前空間名を置き換えるために使用されます。このような展開では、テンプレートを次の例のように作成します。

1 formatVersion: 1
2 inputs:
3 name:
4    type: string
5    title: "Namespace name"
6 resources:
7    Cloud_KBS_Namespace_1:
8        type: Cloud.K8S.Namespace
9        properties:
10            name: ${input.name}

ユーザーは、[インフラストラクチャ] > [リソース] > [Kubernetes クラスタ] ページからアクセス可能な kubeconfig ファイルを使用して、展開されたクラスタを管理できます。目的のクラスタのページでカードを見つけて、[Kubeconfig] をクリックします。

VMware Cloud Templates のスーパーバイザー名前空間

Cloud Assembly クラウド テンプレート内の基本的なスーパーバイザー名前空間のスキームは次のとおりです。

{
  "title": "Supervisor namespace schema",
  "description": "Request schema for provisioning of Supervisor namespace resource",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "description": "Alphabetic (a-z and 0-9) string with maximum length of 63 characters. The character ‘-’ is allowed anywhere except the first or last position of the identifier.",
      "type": "string",
      "pattern": "^.*\\$\\{.*\\}.*$|^((?!-)[a-z0-9-]{1,63}(?<!-))$",
      "ignoreOnUpdate": true
    },
    "description": {
      "title": "Description",
      "description": "An optional description of this Supervisor namespace.",
      "type": "string",
      "ignoreOnUpdate": true
    },
    "content": {
      "title": "Content",
      "description": "Kubernetes Yaml Content",
      "type": "string",
      "maxLength": 65000
    },
    "constraints": {
      "title": "Constraints",
      "description": "To target the correct resources, blueprint constraints are matched against infrastructure capability tags. Constraints must include the key name. Options include value, negative [!], and hard or soft requirement.",
      "type": "array",
      "recreateOnUpdate": true,
      "items": {
        "type": "object",
        "properties": {
          "tag": {
            "title": "Tag",
            "description": "Constraint definition in syntax `[!]tag_key[:tag_value][:hard|:soft]` \nExamples:\n```\n!location:eu:hard\n location:us:soft\n!pci\n```",
            "type": "string",
            "recreateOnUpdate": true
          }
        }
      }
    },
    "limits": {
      "title": "Limits",
      "description": "Defines namespace resource limits such as pods, services, etc.",
      "type": "object",
      "properties": {
        "stateful_set_count": {
          "title": "stateful_set_count",
          "description": "This represents the new value for 'statefulSetCount' option which is the maximum number of StatefulSets in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "deployment_count": {
          "title": "deployment_count",
          "description": "This represents the new value for 'deploymentCount' option which is the maximum number of deployments in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "cpu_limit_default": {
          "title": "cpu_limit_default",
          "description": "This represents the new value for the default CPU limit (in Mhz) for containers in the pod. If specified, this limit should be at least 10 MHz.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "config_map_count": {
          "title": "config_map_count",
          "description": "This represents the new value for 'configMapCount' option which is the maximum number of ConfigMaps in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "pod_count": {
          "title": "pod_count",
          "description": "This represents the new value for 'podCount' option which is the maximum number of pods in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "job_count": {
          "title": "job_count",
          "description": "This represents the new value for 'jobCount' option which is the maximum number of jobs in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "secret_count": {
          "title": "secret_count",
          "description": "This represents the new value for 'secretCount' option which is the maximum number of secrets in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "cpu_limit": {
          "title": "cpu_limit",
          "description": "This represents the new value for 'limits.cpu' option which is equivalent to the maximum CPU limit (in MHz) across all pods in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "cpu_request_default": {
          "title": "cpu_request_default",
          "description": "This represents the new value for the default CPU request (in Mhz) for containers in the pod. If specified, this field should be at least 10 MHz.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "memory_limit_default": {
          "title": "memory_limit_default",
          "description": "This represents the new value for the default memory limit (in mebibytes) for containers in the pod.",
         "type": "integer",
          "recreateOnUpdate": false
        },
        "memory_limit": {
          "title": "memory_limit",
          "description": "This represents the new value for 'limits.memory' option which is equivalent to the maximum memory limit (in mebibytes) across all pods in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "memory_request_default": {
          "title": "memory_request_default",
          "description": "This represents the new value for the default memory request (in mebibytes) for containers in the pod.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "service_count": {
          "title": "service_count",
          "description": "This represents the new value for 'serviceCount' option which is the maximum number of services in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "replica_set_count": {
          "title": "replica_set_count",
          "description": "This represents the new value for 'replicaSetCount' option which is the maximum number of ReplicaSets in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "replication_controller_count": {
          "title": "replication_controller_count",
          "description": "This represents the new value for 'replicationControllerCount' option which is the maximum number of ReplicationControllers in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "storage_request_limit": {
          "title": "storage_request_limit",
          "description": "This represents the new value for 'requests.storage' which is the limit on storage requests (in mebibytes) across all persistent volume claims from pods in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "persistent_volume_claim_count": {
          "title": "persistent_volume_claim_count",
          "description": "This represents the new value for 'persistentVolumeClaimCount' option which is the maximum number of PersistentVolumeClaims in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        },
        "daemon_set_count": {
          "title": "daemon_set_count",
          "description": "This represents the new value for 'daemonSetCount' option which is the maximum number of DaemonSets in the namespace.",
          "type": "integer",
          "recreateOnUpdate": false
        }
      },
      "additionalProperties": false
    },
    "vm_classes": {
      "title": "VM classes",
      "description": "Defines set of Virtual Machine classes to be assigned to the namespace",
      "type": "array",
      "recreateOnUpdate": false,
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "title": "Name",
            "description": "Name of the Virtual Machine class.",
            "type": "string",
            "recreateOnUpdate": false
          }
        }
      }
    },
    "storage": {
      "title": "Storage policies",
      "description": "Defines set of storage profiles to be used to assign storage policies to the namespace.",
      "type": "array",
      "recreateOnUpdate": false,
      "items": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "object",
            "title": "Storage profile",
            "description": "Defines storage policies to be assigned to the namespace",
            "recreateOnUpdate": false,
            "properties": {
              "constraints": {
                "title": "Constraints",
                "description": "To target the correct storage profiles, blueprint constraints are matched against storage profile capability tags.",
                "type": "array",
                "recreateOnUpdate": false,
                "items": {
                  "type": "object",
                  "properties": {
                    "tag": {
                      "title": "Tag",
                      "description": "Constraint definition in syntax `[!]tag_key[:tag_value][:hard|:soft]` \nExamples:\n```\nlocation:eu:hard\n location:us:soft\n```",
                      "type": "string",
                      "recreateOnUpdate": false
                    }
                  }
                },
                "minItems":1
              },
              "limitMb": {
                "title": "Limit",
                "description": "The maximum amount of storage (in mebibytes) which can be utilized by the namespace for this storage policy. Optional. If unset, no limits are placed.",
                "type": "integer"
              }
            },
            "required": [
              "constraints"
            ]
          }
        }
      }
    }
  },
  "required": [
    "name"
  ]
}

VMware Cloud Templates では、スーパーバイザー名前空間に関する制限の使用がサポートされています。制限を使用すると、CPU およびメモリのリソース使用量、および展開されるマシンによって名前空間で許可されるポッドの最大数を制御できます。

formatVersion: 1
inputs: {}
resources:
  Cloud_SV_Namespace_1:
    type: Cloud.SV.Namespace
    properties:
      name: '${env.deploymentName}'
      limits:
        - cpu_limit: 1000
          cpu_request_default: 800
          memory_limit: 2000
          memory_limit_default: 1500
          pod_count: 200

次の例は、タグを使用してストレージ ポリシーを指定する方法を示しています。

formatVersion: 1
inputs: {}
resources:
  Cloud_SV_Namespace_1:
    type: Cloud.SV.Namespace
    properties:
      name: 'ns-with-storage-policy'
      description: 'sample'
      storage: 
        - profile: 
            limitMb: 1000
            constraints: 
              - tag: 'storage:fast'
        - profile: 
            constraints: 
              - tag: 'storage:cheap'

セルフサービス名前空間またはクラスタ VCT での任意の YAML の使用

クラスタまたは名前空間の作成で、ユーザーによる追加のカスタマイズの実行が必要になる場合があります。たとえば、ユーザー(ロールおよびロール バインド)の追加、ポッド セキュリティ ポリシーの作成、エージェントのインストールが必要になる場合があります。YAML の content プロパティを使用することで、ユーザーはそのクラスタ、名前空間、スーパーバイザー名前空間にプロビジョニングするためのカスタマイズされたパッケージを定義できます。

content プロパティに関連付けられている YAML コンテンツ パッケージは、それぞれ 3 つのダッシュ (---) で区切る必要があります。また、コンテンツ情報は複数行の文字列にする必要があります。コンテンツ パッケージの構成方法については、次の YAML の例を参照してください。

formatVersion: 1
inputs: {}
resources:
  Cloud_Tanzu_Cluster_1:
    type: Cloud.Tanzu.Cluster
    properties:
      name: ddonchev-tkc
      plan: small
      content: |-
        apiVersion: rbac.authorization.k8s.io/v1
        kind: ClusterRoleBinding
        metadata:
          name: psp:authenticated-from-yaml
        subjects:
        - apiGroup: rbac.authorization.k8s.io
          kind: Group
          name: system:authenticated
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: psp:vmware-system-privileged
        ---
        apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        metadata:
          # name must match the spec fields below, and be in the form: <plural>.<group>
          name: crontabs.stable.example.com
        spec:
          # group name to use for REST API: /apis/<group>/<version>
          group: stable.example.com
          # list of versions supported by this CustomResourceDefinition
          versions:
            - name: v1
              # Each version can be enabled/disabled by Served flag.
              served: true
              # One and only one version must be marked as the storage version.
              storage: true
              schema:
                openAPIV3Schema:
                  type: object
                  properties:
                    spec:
                      type: object
                      properties:
                        cronSpec:
                          type: string
                        image:
                          type: string
                        replicas:
                          type: integer
          # either Namespaced or Cluster
          scope: Namespaced
          names:
            # plural name to be used in the URL: /apis/<group>/<version>/<plural>
            plural: crontabs
            # singular name to be used as an alias on the CLI and for display
            singular: crontab
            # kind is normally the CamelCased singular type. Your resource manifests use this.
            kind: CronTab
            # shortNames allow shorter string to match your resource on the CLI
            shortNames:
            - ct

コンテンツ プロパティで定義された YAML は、展開の [プロパティ] タブにも表示されます。

Cloud Assembly は、展開されるリソースの範囲内でのみコンテンツ リソースを作成できます。たとえば、Kubernetes 名前空間をプロビジョニングする場合、Cloud Assembly は別の名前空間内に展開を作成することはできません。ユーザーの権限は、kubectl で kubeconfig を使用する場合と同じです。

仮想マシンがプロビジョニングされると、content プロパティ内の Kubernetes オブジェクトのインストールが開始されます。YAML コンテンツのプロパティで参照されているリソースのいずれかがプロビジョニングに失敗すると、Cloud Assembly によってロールバックが実行され、それまでのすべての Kubernetes オブジェクトはリソースから削除され、展開のステータスは [失敗] になります。ただし、リソースは引き続きプロビジョニングされ、表示されます。また、コンテンツの再適用を試行するなど、Day 2 アクションを使用することもできます。

次の例に示すように、クラウド テンプレートからの入力を使用して content プロパティを拡張できます。

formatVersion: 1
inputs: {}
resources:
  Cloud_SV_Namespace_1:
    type: Cloud.SV.Namespace
    properties:
      name: sv-namespace-with-vm-classes
      vm_classes:
        - name: best-effort-2xlarge
        - name: best-effort-4xlarge
        - name: best-effort-8xlarge

さらに、TanzuKubernetesCluster などのカスタム リソースをプロビジョニングすることもできます。これは、スーパーバイザー名前空間に必要な仮想マシン クラスとストレージ クラスが含まれていないため、Day 1 操作としては失敗します。仮想マシン クラスとストレージ クラスがスーパーバイザー名前空間にバインドされている場合は、Day 2 アクションを使用して TanzuKubernetesCluster(または別のリソース)を作成できます。

注:コンテンツがないままでリソースをプロビジョニングし、Day 2 アクションによって Kubernetes オブジェクトを YAML として追加することもできます。

YAML プロパティに表示されるコンテンツにより、リソースにプロビジョニングされる内容が定義されます。このコンテンツを編集した場合に想定される結果を次の表に示します。

アクション 結果
Kubernetes オブジェクトを追加して送信する場合。 指定したオブジェクトがリソース上に作成されます。
Kubernetes オブジェクトを削除して送信した場合。 指定したオブジェクトがリソースから削除されます。
Kubernetes オブジェクトを変更して送信する場合。 指定したオブジェクトにリソース上でパッチが適用されます。

どのアクションが現在のオブジェクトへの変更と見なされるのかを明確にすることが重要です。たとえば、オブジェクトの名前空間フィールドを変更すると、古いオブジェクトが変更されるのではなく新しいオブジェクトが作成されます。

リソースの一意性は、apiVersionkindmetadata.namemetadata.namespace の各フィールドによって定義されます。