Kubernetes 구성 요소를 Cloud Assembly 클라우드 템플릿에 추가할 때 클러스터를 추가하거나 사용자가 다양한 구성으로 네임스페이스를 생성하도록 선택할 수 있습니다. 일반적으로 이러한 선택은 액세스 제어 요구 사항, Kubernetes 구성 요소 구성 방법 및 배포 요구 사항에 따라 결정됩니다.
Kubernetes 구성 요소를 Cloud Assembly의 클라우드 템플릿에 추가하려면 을 선택하고 새로 만들기를 클릭한 다음 왼쪽 메뉴에서 Kubernetes 옵션을 찾아서 확장합니다. 그런 다음 원하는 항목(클러스터 또는 KBS 네임스페이스 중 하나)을 캔버스로 끌어서 선택합니다.
프로젝트와 연결된 Kubernetes 클러스터를 클라우드 템플릿에 추가하는 것은 Kubernetes 리소스를 유효한 사용자가 사용할 수 있게 만드는 가장 간단한 방법입니다. 다른 Cloud Assembly 리소스와 마찬가지로 클러스터에서 태그를 사용하여 배포 위치를 제어할 수 있습니다. 클러스터 배포의 할당 단계에서 태그를 사용하여 영역 및 VMware TKGI(Tanzu Kubernetes Grid Integrated Edition) 계획을 선택할 수 있습니다.
이러한 방식으로 클러스터를 추가하면 유효한 모든 사용자가 자동으로 사용할 수 있게 됩니다.
클라우드 템플릿 예
첫 번째 클라우드 템플릿 예는 태그 지정으로 제어되는 간단한 Kubernetes 배포에 대한 템플릿을 보여줍니다. 새 Kubernetes 영역 페이지에 구성된 두 개의 배포 계획으로 Kubernetes 영역이 생성되었습니다. 이 경우 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
두 번째 클라우드 템플릿 예는 배포를 요청할 때 사용자가 원하는 클러스터 호스트 이름을 입력할 수 있도록 $(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}
사용자는 페이지에서 액세스할 수 있는 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 컨텐츠 패키지는 삼중 대시(---)로 구분해야 합니다. 또한 컨텐츠 정보는 여러 줄 문자열이어야 합니다. 컨텐츠 패키지를 구성할 수 있는 방법을 보려면 다음 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 개체를 모두 롤백하고 삭제하며 배포는 실패 상태가 됩니다. 리소스는 계속 프로비저닝되고 표시됩니다. 또한 컨텐츠를 다시 적용하려는 시도를 비롯한 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와 같은 사용자 지정 리소스를 프로비저닝할 수 있습니다. 이 작업은 1일차 작업으로 실패합니다. 감독자 네임스페이스에는 필요한 가상 시스템 클래스 및 스토리지 클래스가 포함되어 있지 않기 때문입니다. 가상 시스템 클래스 및 스토리지 클래스가 감독자 네임스페이스에 바인딩되면 2일차 작업을 사용하여 TanzuKubernetesCluster(또는 다른 리소스)를 생성할 수 있습니다.
참고: 컨텐츠 없이 리소스를 프로비저닝할 수 있으며 2일차 작업을 통해 kubernetes 개체를 YAML로 추가할 수 있습니다.
YAML 속성에 표시되는 컨텐츠는 리소스에 프로비저닝되는 항목을 정의합니다. 이 컨텐츠를 편집하면 다음 표에 가능한 결과가 표시됩니다.
| 작업 | 결과 |
|---|---|
| kubernetes 개체를 추가하고 제출하면, | 지정된 개체가 리소스에 생성됩니다. |
| kubernetes 개체를 제거하고 제출하면, | 지정된 개체가 리소스에서 삭제됩니다. |
| kubernetes 개체를 수정하고 제출하면, | 지정된 개체가 리소스에 패치됩니다. |
현재 개체에 대해 어떤 작업이 수정으로 간주되는지 명확히 하는 것이 중요합니다. 예를 들어 개체의 네임스페이스 필드를 수정하면 이전 개체에 패치가 적용되는 대신 새 개체가 생성됩니다.
리소스의 고유성은 apiVersion, kind, metadata.name, metadata.namespace 필드로 정의됩니다.