Концепции
dhctl
Чтобы установить Deckhouse Kubernetes Platform вручную, используют утилиту dhctl. На вход она принимает три набора данных:
- Конфигурацию SSH-подключения к машине, которая станет первым мастер-узлом. Конфигурация
используется в виде ключей командной строки dhctl (есть возможность задать в виде YAML). Будем
далее ссылаться на него под именем 
SSHConfig. - Инфраструктурная и базовая конфигурация кластера в виде yaml-файла, будем
далее ссылаться на него под именем 
config.yaml. - Необязательный набор ресурсов который нужно создать на последнем шаге установки, будем далее
ссылаться на него под именем 
resources.yaml. 
Соответствие имен файлов и их содержимое приведено только для наглядности и совместимости со старыми версиями dhctl. Современные версии dhctl не ограничивают пользователя количеством и именами конфигурационных файлов для установки.
Какие логические части содержатся в этих данных?
SSHConfig- Имя пользователя, пароль и ключ для подключения к существующей машине или той, которая будет создана в процессе создания кластера (возможность задать пароль для sudo в разработке).
 - IP-адрес машины, если кластер разворачивается на заранее созданных машинах («статический» тип кластера)
 - Остальные параметры можно посмотреть в справке команды dhctl, в данной документации дополнительные детали несущественны
 
InitConfiguration— конфигурация доступа в реестр контейнеров (dockerconfig)ClusterConfiguration— конфигурация Kubernetes: версия, подсетей подов, сервисов и т.п.- Параметры размещения в инфраструктуре
<Provider>ClusterConfiguration— параметры размещения кластера в облаке или API виртуализации, если Deckhouse Kubernetes Platform устанавливается не на статические ресурсы;- или 
StaticClusterConfigurationдля статического кластера 
 
- Параметры размещения в инфраструктуре
 resources.yaml— произвольная конфигурация Deckhouse Kubernetes Platform в виде манифестов Kubernetes
Все эти данные в разных комбинациях используются для создания, изменения и удаления кластеров. Эти же данные используются в Deckhouse Commander, а dhctl используется как внутренний компонент.
Deckhouse Commander
Deckhouse Commander использует тот же набор данных для конфигурации кластеров, что и dhctl. Это включает в себя параметры подключения (SSHConfig),
конфигурация Kubernetes (ClusterConfiguration, <Provider>ClusterConfiguration и StaticClusterConfiguration), произвольные манифесты (resources.yaml).
Однако в Deckhouse Commander пользователь не сталкивается напрямую с конфигурированием InitConfiguration. Вместо этого
используется конфигурация реестров через специальные формы. Данные из этих форм автоматически преобразуются в InitConfiguration
и передаются в dhctl. Обратим внимание, что конфигурация реестров в Deckhouse Commander не связана с конфигурацией шаблона, но
является необходимым шагом для рендеринга шаблона и для создания кластера.
Deckhouse Commander добавляет возможность автоматически синхронизировать полную желаемую конфигурацию с кластером.
| Вид конфигурации | Часть конфигурации | Установка | Изменение | Удаление | 
|---|---|---|---|---|
| Доступ | SSH-подключение к мастер-узлу | ✓ | ✓ | |
| Доступ | Реестр контейнеров | ✓ | ||
| Инфраструктура/Доступ | Размещение<Provider>ClusterConfiguration | 
          ✓ | ✓ | ✓ | 
| Инфраструктура/Kubernetes | KubernetesClusterConfiguration | 
          ✓ | ✓ | |
| Kubernetes | Операционная конфигурация платформы | ✓ | ✓ | 
- Для создания и удаления кластера требуется SSH-доступ к мастер-узлу, а для изменений не требуется.
 - Доступ в реестр контейнеров настраивается только во время установки (в будущем будет возможность управлять изменением параметров реестр)
 - Базовая инфраструктурная конфигурация управляется с помощью доступа в API облака, в то время как операционная конфигурация используется с помощью commander-agent (далее — «агент») — вспомогательного модуля, который включается в кластере в процессе его создания или присоединения к Deckhouse Commander.
 
Deckhouse Commander — источник истины конфигурации. Deckhouse Commander отслеживает, что конфигурация кластера соответствует заданной. Если Deckhouse Commander обнаруживает расхождение, он принимает попытку привести кластер к заданной конфигурации. Далее для этого мы будем использовать «синхронизация».
- Синхронизация инфраструктуры проводится компонентом cluster-manager, который использует dhctl.
 - Синхронизация операционной конфигурации проводится компонентом агентом.
 
Deckhouse Commander делит конфигурацию Deckhouse Kubernetes Platform по принципу отслеживаемости. Причем пользователь решает какую часть конфигурации синхронизировать, а какую задать один раз при создании кластера. Как эта конфигурация выглядит с точки зрения Deckhouse Commander:
| Вид конфигурации | Часть конфигурации | Актуализирующий компонент | 
|---|---|---|
| Доступ | SSH-подключение к мастер-узлу | — | 
| Доступ | Реестр контейнеров | cluster-manager | 
| Инфраструктура/Доступ | Размещение<Provider>ClusterConfiguration | 
          cluster-manager | 
| Инфраструктура/Kubernetes | KubernetesClusterConfiguration | 
          cluster-manager | 
| Kubernetes | Операционная конфигурация платформы | commander-agent | 
Шаблоны
Идея
Deckhouse Commander создан для того, чтобы управлять типовыми кластерами. Так как все виды конфигурации в Deckhouse Commander представлены в формате YAML, шаблонизация кластеров представляет собой шаблоны YAML-конфигурации и описание схемы этих входных параметров шаблона. Для шаблонизации YAML используется синтаксис go template и набор функций sprig. Для описания схемы входных параметров используется собственный синтаксис для полей.
| Секция | Тип | Назначение | 
|---|---|---|
| Входные параметры | Схема | Схема входных параметров шаблона | 
| Kubernetes | Шаблон YAML | Конфигурация KubernetesClusterConfiguration | 
      
| Размещение | Шаблон YAML | Конфигурация размещения<Provider>ClusterConfiguration или StaticClusterConfiguration | 
      
| Параметры SSH | Шаблон YAML | SSH-подключение к мастер-узлу | 
| Ресурсы | Шаблон YAML | Ресурсы кластера, включая любые ModuleConfig кроме системных | 
      
| Первичные ресурсы | Шаблон YAML | Ресурсы кластера, включая любые ModuleConfig кроме системных | 
      
| Установка | Шаблон YAML | Конфигурация установки системные ModuleConfig | 
      
Конфигурация кластера создается за счет подстановки входных параметров в шаблоны секций. Входные параметры валидируются заданной для них схемой.
Версии шаблона
Важная черта шаблона — эволюция. Недостаточно создать парк кластеров на основе шаблонов. Шаблоны совершенствуются и актуализируются под новые версии ПО и новые требования эксплуатации кластеров. Обновленный шаблон позволяет не только создавать новые кластера, отвечающие современным требованиям, но и для того, чтобы актуализировать уже существующие кластеры.
Для эволюции шаблонов в Deckhouse Commander предусмотрен механизм версионирования. Когда шаблон получает обновления, для него создается новая версия. Версия может быть сопровождена комментарием. На основе версии шаблона можно создать кластер и протестировать его работоспособность. Если версия шаблона не подходит для того, чтобы ею пользовались, ее можно отметить недоступной для использования. Тогда администраторы кластеров не смогут перевести кластер на версию шаблона.
В Deckhouse Commander каждый кластер привязан к определенной версии шаблона. Однако технически кластер можно перевести на любой другой шаблон и любую доступную версию шаблона с точностью до невалидной конфигурации, которую Deckhouse Commander не позволит сохранить. Когда кластер переводится на новую версию или шаблон, необходимо актуализировать входные параметры, чтобы для кластера создалась обновленная конфигурация. Deckhouse Commander обнаружит, что целевая конфигурация не совпадает с последней примененной конфигурацией и создаст задание на синхронизацию кластера.
Сложность шаблона
Создание и тестирование шаблона — это инженерная задача, в то время как создание кластеров на основании шаблона не требует глубокого погружения в технические особенности в общем случае.
Входные параметры шаблона представлены для пользователя в виде онлайн-формы, в которой пользователь набирает или выбирает параметры, необходимые для создания кластера. Весь набор входных параметров определяется автором шаблона: какие параметры доступны, какие обязательны, в каком порядке заполняются, каким тестом сопровождены и как отформатированы для удобства восприятия конечным пользователем.
Только автор шаблона определяет, насколько будет просто или тяжело использовать шаблон конечному пользователю, и какие решения необходимо пользователю принять, чтобы успешно создать кластер. Чем сложнее шаблон, тем сложнее шаблонизирующий его код и тем сложнее форма параметров шаблона. Пользователи Deckhouse Commander сами определяют соотношение сложности шаблона и количества шаблонов для разных сценариев. Deckhouse Commander — достаточно гибкий инструмент. С ним можно сделать как один шаблон на все случаи жизни, так и множество шаблонов для каждого отдельного сценария использования.
Создание шаблона
Добавить шаблон в Deckhouse Commander можно двумя способами: импортировать существующий (например, созданный ранее в другой инсталляции Deckhouse Commander) или создать с нуля. В конечном счете шаблонизированная конфигурация должна будет удовлетворять особенностями dhctl и Deckhouse Kubernetes Platform той версии, которая будет устанавливаться с помощью шаблона.
Где почерпнуть документацию для видов конфигурации
- Входные параметры
 - Размещение
 - Kubernetes
 - Доступ в реестр контейнеров
- Конфигурация реестров в Deckhouse Commander
 - InitConfiguration (данный конфигурационный файл не редактируется напрямую, а генерируется автоматически).
 
 - Параметры SSH
- См. примеры ниже
 
 
Специальные переменные
В шаблонах кластеров есть несколько специальных переменных.
| Переменная | Назначение | 
|---|---|
dc_sshPublicKey | 
          Публичная часть SSH-ключа. Пара SSH-ключей создается для каждого кластера. Можно использовать для cloud-init облачных кластеров.  | 
      
dc_sshPrivateKey | 
          Приватная часть SSH-ключа. Пара SSH-ключей создается для каждого кластера. Можно использовать для доступа к мастер-узлам облачных кластеров.  | 
      
dc_clusterUUID | 
          UUID текущего кластера. Генерируется для каждого кластера. Можно использовать для тегирования метрик и логов кластера.  | 
      
dc_domain | 
          Домен, на котором размещен Deckhouse Commander. Общий для всего приложения.  Пример: commander.example.com | 
      
dc_caBundle | 
          Сертификат Deckhouse Commander, закодированный в base64. Используется агентом для верификации подключений к серверу Deckhouse Commander.  | 
      
Параметры SSH для облачного кластера
Для облачного кластера можно использовать приватный ключ, созданный Deckhouse Commander, если вы не предоставляете заранее определенный ключ в образе ОС. Также в образах виртуальных машин будет создан пользователь, под которым Deckhouse Commander подключится к созданной машине, чтобы завести ее как master-узел.
apiVersion: dhctl.deckhouse.io/v1
kind: SSHConfig
# имя пользователя для SSH, определяется образом ОС в разделе «Размещение»
sshUser: ubuntu
sshPort: 22
# приватный ключ, который будет использовать для подключения к ВМ по SSH
sshAgentPrivateKeys:
- key: |
    {{- .dc_sshPrivateKey | nindent 4 }}
Параметры SSH и ресурсы для статического кластера
Так как машины созданы заранее, и на них настроен сервер SSH, пользователь и ключ, то эти данные необходимо сообщить во входных параметрах кластера. В отличие от облачной конфигурации выше, мы используем не встроенный параметр, а явно переданный пользователем. Часть данных всегда можно задать внутри шаблона, если их параметризация не представляется целесообразной.
Обратите внимание на манифесты SSHHost. Они объявляют IP-адреса, к которому у Deckhouse Commander есть
доступ. В данном примере предполагается, что входной параметр .masterHosts — это список
IP-адресов, на основании которых в конфигурации будет набор SSH-хостов. Так как это мастера, их
следует указывать в количестве 1 или 3.
apiVersion: dhctl.deckhouse.io/v1
kind: SSHConfig
# имя пользователя и порт для SSH, сконфигурированные на машинах
sshUser: {{ .sshUser }}
sshPort: {{ .sshPort }}
# приватный ключ, используемый на машинах, передается как входной параметр в кластер
sshAgentPrivateKeys:
- key: |
    {{- .sshPrivateKey | nindent 4 }}
{{- range $masterHost := .masterHosts }}
---
apiVersion: dhctl.deckhouse.io/v1
kind: SSHHost
host: {{ $masterHost.ext_ip }}
{{- end }}
Deckhouse Commander подключится только к одному SSH-хосту в переданном списке, будет пробовать хосты по
порядку до первого успешного подключения. Первый подключенный хост станет мастер-узлом кластера.
Когда Deckhouse установится на первом мастер-узле, он сможет сам добавить два оставшихся мастер-узла
в кластер, если они заявлены в шаблоне. Для этого нужно сообщить Deckhouse, что машины существуют,
как на них попасть, и что их нужно добавить в кластер. Для этого необходимо для двух мастеров
создать StaticInstance, определить для них SSHCredentials, а также явно прописать группу узлов
master с параметром spec.staticInstances.count=2, чтобы два статических мастер-узла не только были
известны Deckhouse, но и были востребованы как master-узлы. Эту часть шаблона целесообразно
определить в «Ресурсах». Ниже представлен код шаблона для этой задачи:
---
apiVersion: deckhouse.io/v1alpha1
kind: SSHCredentials
metadata:
  name: commander-ssh-credentials
  labels:
    heritage: deckhouse-commander
spec:
  sshPort: {{ .sshPort }}
  user: {{ .sshUser }}
  privateSSHKey: {{ .sshPrivateKey | b64enc }}
{{- if gt (len .masterHosts) 1 }}
{{-   range $masterInstance := slice .masterHosts 1 }}
---
apiVersion: deckhouse.io/v1alpha1
kind: StaticInstance
metadata:
  labels:
    type: master
    heritage: deckhouse-commander
  name: {{ $masterInstance.hostname | quote }}
spec:
  address: {{ $masterInstance.ip | quote }}
  credentialsRef:
    apiVersion: deckhouse.io/v1alpha1
    kind: SSHCredentials
    name: commander-ssh-credentials
{{-   end }}
{{- end }}
{{- if gt (len .masterHosts) 1 }}
---
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
  name: master
  labels:
    heritage: deckhouse-commander
spec:
  disruptions:
    approvalMode: Manual
  nodeTemplate:
    labels:
      node-role.kubernetes.io/control-plane: ""
      node-role.kubernetes.io/master: ""
    taints:
    - effect: NoSchedule
      key: node-role.kubernetes.io/master
    - effect: NoSchedule
      key: node-role.kubernetes.io/control-plane
  nodeType: Static
  staticInstances:
    count: 2
    labelSelector:
      matchLabels:
        type: master
{{- end }}
Ресурсы: модуль commander-agent
Deckhouse Commander синхронизирует ресурсы с помощью модуля commander-agent. Этот модуль устанавливается в целевом кластере. Приложение commander-agent запрашивает актуальный список ресурсов для кластера и актуализирует их в кластере, в котором работает. настроен, в ресурсах необходимо создать манифест, включающий модуль.
Обратите внимание на commanderUrl. Вам предстоит уточнить схему этого адреса: HTTP или HTTPS.
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: commander-agent
  labels:
    heritage: deckhouse-commander
spec:
  enabled: true
  version: 1
  settings:
    commanderUrl: "https://{{ .dc_domain }}/agent_api/{{ .dc_clusterUUID }}"
Схема параметров кластера и записи инвентаря
Есть две формы, которые пользователь собирает с помощью схемы:
- форма параметров кластера (входные параметры шаблона кластера),
 - форма записи.
 
Схема определяет объект. Всегда есть возможность редактировать ее в визуальном редакторе формы.
Общедоступные поля
Ввод строки
Строка со значением по умолчанию
- key: something
  type: string
  title: Некое значение
  default: Ввода нет
Необязательный параметр, его разрешено не заполнять (optional)
- key: something
  type: string
  title: Некое значение
  optional: true
Параметр заполняется один раз при создании записи или кластера, и далее его нельзя редактировать
(immutable)
- key: something
  type: string
  title: Некое значение
  immutable: true
Пароль и пояснение к нему (см format и description)
- key: password
  type: string
  format: password
  minLength: 8
  span: 2
  title: Пароль
  description: |
    Придумайте нормальный пароль.
    Пароль должен содержать то-то и то-то и обновляться каждые N дней.
Ввод числа
Можно задать максимум и необязательность
- key: ordinarySize
  type: number
  optional: true
  max: 13
Можно задать минимум и сделать поле ввода на 4 колонки (максимальная ширина)
- key: eliteSize
  type: number
  description: In cm
  min: 18
  span: 4
Можно задать максимум и минимум
- key: elephantSize
  type: number
  description: In meters
  min: 0.7
  max: 2.5
  span: 1
Ввод предопределенных значений
Простые значения
Выбор из заранее заданных значений. В интерфейсе пользователь видит то значение, которое выбирает
- key: kubeVersion
  type: string
  title: Версия Kubernetes
  enum:
    - Automatic
    - "1.25"
    - "1.26"
    - "1.27"
Сложные значения
Выбор из заранее заданных объектных значений. В интерфейсе пользователь видит значение из text, в
то время как для шаблона технически выбирается value. Обратите внимание, что в value доступны
только значения типа object (ключ-значение). Это значение не описывается схемой, структура объекта
произвольна.
- key: kubeVersion
  title: Версия Kubernetes
  select:
    - text: По умолчанию
      value:
        version: Automatic
        isSupported: true
    - text: 1.25 (поддержка закончится в марте)
      value:
        version: 1.25.8
        isSupported: true
    - text: 1.26
      value:
        version: 1.26.4
        isSupported: true
    - text: 1.27
      value:
        version: 1.27.3
        isSupported: true
    - text: 1.28 (экспериментальная)
      value:
        version: 1.28.0
        isSupported: false
Поля, доступные в шаблоне кластера
Выбор одной записи из каталога
Каталоги имеют неизменяемое техническое имя (slug). Оно указывается в свойстве catalog:
- key: slot
  catalog: yandex-cloud-slot
  title: Слот для кластера
  immutable: true
  description: >
    Выберите букву. Она определит домен, префикс в облаке и IP-адрес. Этот слот
    уникален для всех кластеров независимо от шаблона.
    Допустим вы выбрали `N`. Шаблон домена будет `%s.X.kube.example.com`. Рекомендуем назвать кластер `dev-X`
    Логин и пароль — всегда `admin@example.com`
Выбор нескольких записей
Множественный выбор обеспечивается парой свойств: minItems и maxItems. Любое поле можно сделать
списком данных, если указать оба этих поля.
- key: slot
  catalog: virtual-machines
  title: Воркер-узлы
  description: Сколько угодно воркеров, можно редактировать
  minItems: 0
  maxItems: 10000
Автовыбор
Иногда пользователю неважно, какая именно запись будет выбрана из каталога. Поэтому авто-выбор делает подстановку свободной записи автоматически. Автоматически выбранную запись можно заменить вручную на другой.
- key: publicAddressesForFrontendNodes
  title: Публичные адреса
  catalog: public-ip-addresses
  minItems: 3
  maxItems: 3
  autoselect: true
Составные части
Разделитель
header
- Тип: string
 
Единственный тип разделителя — заголовок. Он поддерживает только текст. Других свойств у него нет.
- header: Доступ к образам
Свойства полей ввода
key
- Тип: string
 
Значение поля ввода нужно идентифицировать в шаблоне. Поэтому всегда должно быть свойство поля key — это имя поля будет использоваться в шаблоне во время рендеринга конфигурации.
- Обязательное поле
 
В схеме:
- key: podSubnet
  title: Подсеть подов
  type: string
В шаблоне:
podSubnet: {{.podSubnet | quote }}
type
- Тип: string
 - Обязательное поле
 - Допустимые значения:
stringnumberboolean
 
У значения есть заранее заданный тип: строка, число или булевый.
title
- Тип: string
 - Обязательное поле
 
У поля есть название, передающее смысл. Это одна строка текста. Оно отображается в форме параметров и в аудите.
description
- Тип: string
 
У поля может быть комментарий, раскрывающий смысл, объясняющий граничные условия, формат записи или исключения. Может быть несколько строк текста.
default
- Тип: зависит от 
type 
Значение по умолчанию заполняется, если поле отмечено необязательным. Также это значение показано
пользователю, например, в виде подсказки. Тип значения этого свойства должен совпадать с type.
format
- Тип: string
 
У строк может быть формат, который определит особенности отображения и особенности валидации значений.
- Допустимые значения:
passworddate-timeurlemailuuidcuidcuid2ulidemoji
 
span
- Тип: number
 - Допустимые значения: 
1,2,3,4 - По умолчанию: 
1 
Это декоративное свойство, которое указывает, какую ширину занять на экране в долях: от 1 до 4. Поля ввода заполняют форму построчно по горизонтали, как текст. При этом ширина «строки» формы — это 4 элемента.
optional
- Тип: boolean
 - По умолчанию: 
false 
Этот флаг говорит о том, что поле необязательное. Пустое значение будет проигнорировано, и свойство не будет передано в шаблон.
immutable
- Тип: boolean
 - По умолчанию: 
false 
Этот флаг говорит о том, что поле заполняется только один раз, когда появляется во входных параметрах. Это поле становится недоступным для редактирования, если оно было уже заполнено. Это означает, что при обновлении кластера на новый шаблон с immutable-полем, его можно заполнить. Иммутабельность зависит от жизненного цикла параметра в форме, а не кластера.
enum
- Тип: array
 
Перечисляет допустимые значения, которое принимает поле. Поле представляет собой селект независимо
для типа значения, выбранного в type.
selector
- Тип: array
 
Это более сложный вариант enum. В нем заложено строковое представление объекта (text) и
произвольно сложное значение в value, которое будет выбрано для шаблона. Текст указывают для
людей, а значения — для шаблона.
Пример:
- key: kubeVersion
  title: Версия Kubernetes
  select:
    - text: По умолчанию
      value:
        version: Automatic
        isSupported: true
    - text: 1.25 (поддержка закончится в марте)
      value:
        version: 1.25.8
        isSupported: true
    - text: 1.26
      value:
        version: 1.26.4
        isSupported: true
    - text: 1.27
      value:
        version: 1.27.3
        isSupported: true
    - text: 1.28 (экспериментальная)
      value:
        version: 1.28.0
        isSupported: false
catalog
- Тип: string
 
Выбор одного значения из каталога. В значение вписать slug каталога. Поле type
указывать не нужно, потому что фактически это object, схема которого описана в указанном каталоге.
Чтобы выбрать несколько значений (и получить список записей на входе в шаблон), используйте
minItems и maxItems.
Пример:
- key: workerMachine
  title: Виртуальная машина
  catalog: virtual-machines
- key: workerMachines
  title: Виртуальные машины
  catalog: virtual-machines
  minItems: 1
  maxItems: 10
maxLength (для строки)
- Тип: number
 
Для type: string это поле добавляет валидацию на длину строки
minItems, maxItems (для выбора записей)
- Тип: number
 
Валидация количества элементов выбранных из каталога. Эта пара полей необязательна, но использовать их порознь запрещено: если использовать, то оба сразу.
autoselect (для выбора записей)
- Тип: boolean
 - По умолчанию: 
false 
Иногда пользователю не столь важно, какая именно запись будет выбрана. Тогда форма выбирает сама за пользователя доступные записи. Но у пользователя при этом всегда есть возможность их изменить.
Пример:
- key: publicAddressesForFrontendNodes
  title: Публичные адреса
  catalog: public-ip-addresses
  minItems: 3
  maxItems: 3
  autoselect: true
identifier
- Тип: boolean
 - По умолчанию: зависит от заполнения
 
Запись — это плоский объект. У записи есть компактное представление в одну строку, составленное из
значений полей записи (без ключей). Значения записи указаны через запятую в порядке, заданной
схемой. Это компактное представление можно видеть как в перечне записей внутри каталога, так и в
выборе записи в форме кластера (выпадающие списки). Чтобы выбрать ограниченный набор полей для
компактного отображения записи, используйте свойство identifier.
Например, рассмотрим запись и возможные варианты ее схемы
## Запись
login: anatoly
password: E3xE#%DH@hW
age: 42
| Использовать все поля | Спрятать | Показывать явно | |
|---|---|---|---|
| Схема | 
 | 
 | 
 | 
| Представление | 
 
  | 
 
  | 
 
  | 
| Поведение | 
 По умолчанию для всех полей   | 
 По умолчанию для всех полей   | 
 Если явно указано   | 
unique
- Тип: boolean
 - По умолчанию: 
false 
Этим флагом помечаются поля записи, которые должны быть уникальными в рамках каталога. Неуникальные данные запрещено создавать, восстанавливать из архива или импортировать.
Также этим флагом помечаются поля кластера, которые должны быть уникальными среди всех кластеров. Неуникальные данные запрещено сохранять: создание и редактировать кластера завершится с ошибкой валидации.
Выбор из каталога для кластеров уникален настолько, насколько уникальны записи. Выбор из каталога не требуется отмечать этим флагом.
- key: subnetCIDR
  type: string
  title: CIDR подсети
  unique: true