Beim Hinzufügen von Kubernetes-Komponenten zu einer Cloud Assembly-Cloud-Vorlage können Sie Cluster hinzufügen oder Benutzern das Erstellen von Namespaces in verschiedenen Konfigurationen ermöglichen. Diese Auswahl hängt in der Regel von Ihren Anforderungen an die Zugriffssteuerung, von der Konfiguration Ihrer Kubernetes-Komponenten und von Ihren Bereitstellungsanforderungen ab.

Zum Hinzufügen einer Kubernetes-Komponente zu einer Cloud-Vorlage in Cloud Assembly wählen Sie Design > Cloud-Vorlagen aus, klicken auf Neu, suchen anschließend nach der Kubernetes-Option im linken Menü und erweitern die Option. Nehmen Sie dann die gewünschte Auswahl vor, entweder „Cluster“ oder „KBS-Namespace“, indem Sie sie auf die Arbeitsfläche ziehen.

Das Hinzufügen eines mit einem Projekt verknüpften Kubernetes-Clusters zu einer Cloud-Vorlage stellt die einfachste Methode dar, Kubernetes-Ressourcen für gültige Benutzer zur Verfügung zu stellen. Wie andere Cloud Assembly-Ressourcen können Sie Tags in Clustern verwenden, um deren Bereitstellungsort zu steuern. Sie können Tags zum Auswählen einer Zone und eines VMware Tanzu Kubernetes Grid Integrated Edition-Plans (TKGI) während der Zuteilungsphase der Clusterbereitstellung verwenden.

Sobald Sie einen Cluster auf diese Weise hinzugefügt haben, steht er automatisch allen gültigen Benutzern zur Verfügung.

Beispiele für Cloud-Vorlagen

Das erste Beispiel zeigt eine Vorlage für eine einfache Kubernetes-Bereitstellung, die durch Tagging gesteuert wird. Eine Kubernetes-Zone wurde mit zwei Bereitstellungsplänen erstellt, die auf der Seite „Neue Kubernetes-Zone“ konfiguriert wurden. In diesem Fall wurde der Zone ein Tag mit dem Namen placement:tag als Funktion hinzugefügt, das zum Abgleichen der analogen Einschränkung in der Cloud-Vorlage verwendet wurde. Wenn mehr als eine Zone mit dem Tag konfiguriert ist, wird diejenige mit der niedrigsten Prioritätsnummer ausgewählt.

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 

Im zweiten Beispiel wird die Einrichtung einer Cloud-Vorlage mit einer Variable mit dem Namen $(input.hostname) dargestellt, damit Benutzer beim Anfordern einer Bereitstellung den gewünschten Cluster-Hostnamen eingeben können. Tags können auch verwendet werden, um eine Zone und einen TKGI-Plan während der Ressourcenzuteilungsphase der Clusterbereitstellung auszuwählen.

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

Wenn Sie Namespaces zum Verwalten der Cluster-Nutzung verwenden möchten, können Sie in der Cloud-Vorlage eine Variable mit dem Namen name: ${input.name} einrichten, um den Namespace-Namen zu ersetzen, den ein Benutzer beim Anfordern einer Bereitstellung eingibt. Für diese Art der Bereitstellung erstellen Sie eine Vorlage ähnlich dem folgenden Beispiel:

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}

Benutzer können bereitgestellte Cluster über kubeconfig-Dateien verwalten, auf die von der Seite Infrastruktur > Ressourcen > Kubernetes-Cluster zugegriffen werden kann. Suchen Sie die Karte auf der Seite für den gewünschten Cluster und klicken Sie auf Kubeconfig.

Supervisor-Namespaces in VMware Cloud Templates

Nachstehend finden Sie das Schema für einen einfachen Supervisor-Namespace in einer Cloud Assembly-Cloud-Vorlage.

{
  "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 unterstützen die Verwendung von Grenzwerten in Verbindung mit Supervisor-Namespaces. Mit Grenzwerten können Sie die Ressourcennutzung für CPUs und Arbeitsspeicher sowie die maximale Anzahl von Pods, die im Namespace von den bereitgestellten Maschinen zugelassen werden, steuern.

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

In folgendem Beispiel wird die Angabe einer Speicherrichtlinie mithilfe von Tags dargestellt.

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'

Verwenden beliebiger YAMLs mit Self-Service-Namespace oder Cluster-VCTs

Im Rahmen der Erstellung eines Clusters oder Namespace möchten Benutzer häufig zusätzliche Anpassungen ausführen. Sie möchten beispielsweise Benutzer (Rolle/Rollenbindung) hinzufügen, eine Pod-Sicherheitsrichtlinie erstellen oder Agents installieren. Mithilfe der YAML-Eigenschaft content können Benutzer benutzerdefinierte Pakete definieren, die sie in diesem Cluster/Namespace/Supervisor-Namespace bereitstellen möchten.

Jedes mit der Eigenschaft content verknüpfte YAML-Inhaltspaket muss mit drei Bindestrichen (---) abgetrennt werden. Darüber hinaus müssen die Inhaltsinformationen eine mehrzeilige Zeichenfolge sein. Im folgenden YAML-Beispiel erhalten Sie Informationen zum Konfigurieren von Inhaltspaketen.

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

Die in der Inhaltseigenschaft definierte YAML wird auch auf der Registerkarte „Eigenschaften“ für die Bereitstellung angezeigt.

Cloud Assembly kann Inhaltsressourcen nur im Bereich der bereitgestellten Ressource erstellen. Beispiel: Wenn Sie einen Kubernetes-Namespace bereitstellen, kann Cloud Assembly keine Bereitstellung in einem anderen Namespace erstellen. Benutzer haben dieselben Rechte wie bei der Verwendung von kubeconfig mit kubectl.

Nach der Bereitstellung der virtuellen Maschine beginnt eine Installation der Kubernetes-Objekte innerhalb der Eigenschaft content. Wenn eine der Ressourcen, auf die in der YAML-Inhaltseigenschaft verwiesen wird, nicht bereitgestellt werden kann, führt Cloud Assembly ein Rollback durch und löscht alle vorherigen Kubernetes-Objekte aus der Ressource. Die Bereitstellung weist dann den Status „Fehlgeschlagen“ auf. Die Ressource wird weiterhin bereitgestellt und angezeigt. Darüber hinaus können Sie weiterhin Tag-2-Aktionen verwenden, einschließlich der erneuten Anwendung des Inhalts.

Sie können die Eigenschaft content mit Eingaben aus der Cloud-Vorlage entsprechend folgendem Beispiel erweitern.

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

Darüber hinaus können Sie benutzerdefinierte Ressourcen wie den TanzuKubernetesCluster bereitstellen. Dies würde als Tag-1-Vorgang fehlschlagen, da der Supervisor-Namespace nicht die erforderlichen VM-Klassen und Speicherklassen enthält. Wenn die VM- und Speicherklassen an den Supervisor-Namespace gebunden sind, können Sie den TanzuKubernetesCluster (oder eine andere Ressource) mithilfe der Tag-2-Aktion erstellen.

Hinweis: Sie können eine Ressource ohne Inhalt bereitstellen, Kubernetes-Objekte aber dennoch mithilfe der Tag-2-Aktion als YAML hinzufügen.

Der in der YAML-Eigenschaft angezeigte Inhalt definiert die in der Ressource bereitgestellten Elemente. Wenn Sie diesen Inhalt bearbeiten, werden in der folgenden Tabelle die möglichen Ergebnisse angezeigt:

Aktion Ergebnis
Hinzufügen eines Kubernetes-Objekts und Übermittlung. Das angegebene Objekt wird auf der Ressource erstellt.
Entfernen eines Kubernetes-Objekts und Übermittlung. Das angegebene Objekt wird aus der Ressource gelöscht.
Bearbeiten eines Kubernetes-Objekts und Übermittlung. Das angegebene Objekt wird auf die Ressource gepatcht.

Es ist zu klären, welche Aktionen als Änderungen am aktuellen Objekt betrachtet werden. Beispiel: Wenn Sie das Namespace-Feld eines Objekts ändern, wird ein neues Objekt erstellt, anstatt das alte zu patchen.

Die Eindeutigkeit einer Ressource wird durch folgende Felder definiert: apiVersion, kind, metadata.name, metadata.namespace